Skip to content

Commit 9627e4f

Browse files
authored
Merge pull request #6 from elixir-lang/fix-nothing-to-index
[bugfix] Only index if there's stuff to index
2 parents 47729d7 + 3a9a789 commit 9627e4f

File tree

2 files changed

+85
-52
lines changed

2 files changed

+85
-52
lines changed

apps/remote_control/lib/lexical/remote_control/search/indexer.ex

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -101,57 +101,62 @@ defmodule Lexical.RemoteControl.Search.Indexer do
101101

102102
total_bytes = paths_to_sizes |> Enum.map(&elem(&1, 1)) |> Enum.sum()
103103

104-
{on_update_progess, on_complete} = Progress.begin_percent("Indexing source code", total_bytes)
104+
if total_bytes > 0 do
105+
{on_update_progess, on_complete} =
106+
Progress.begin_percent("Indexing source code", total_bytes)
105107

106-
initial_state = {0, []}
108+
initial_state = {0, []}
107109

108-
chunk_fn = fn {path, file_size}, {block_size, paths} ->
109-
new_block_size = file_size + block_size
110-
new_paths = [path | paths]
110+
chunk_fn = fn {path, file_size}, {block_size, paths} ->
111+
new_block_size = file_size + block_size
112+
new_paths = [path | paths]
111113

112-
if new_block_size >= @bytes_per_block do
113-
{:cont, new_paths, initial_state}
114-
else
115-
{:cont, {new_block_size, new_paths}}
114+
if new_block_size >= @bytes_per_block do
115+
{:cont, new_paths, initial_state}
116+
else
117+
{:cont, {new_block_size, new_paths}}
118+
end
116119
end
117-
end
118120

119-
after_fn = fn
120-
{_, []} ->
121-
{:cont, []}
121+
after_fn = fn
122+
{_, []} ->
123+
{:cont, []}
122124

123-
{_, paths} ->
124-
{:cont, paths, []}
125-
end
126-
127-
paths_to_sizes
128-
|> Stream.chunk_while(initial_state, chunk_fn, after_fn)
129-
|> Task.async_stream(
130-
fn chunk ->
131-
block_bytes = chunk |> Enum.map(&Map.get(path_to_size_map, &1)) |> Enum.sum()
132-
result = Enum.map(chunk, processor)
133-
on_update_progess.(block_bytes, "Indexing")
134-
result
135-
end,
136-
timeout: timeout
137-
)
138-
|> Stream.flat_map(fn
139-
{:ok, entry_chunks} -> entry_chunks
140-
_ -> []
141-
end)
142-
# The next bit is the only way i could figure out how to
143-
# call complete once the stream was realized
144-
|> Stream.transform(
145-
fn -> nil end,
146-
fn chunk_items, acc ->
147-
# By the chunk items list directly, each transformation
148-
# will flatten the resulting steam
149-
{chunk_items, acc}
150-
end,
151-
fn _acc ->
152-
on_complete.()
125+
{_, paths} ->
126+
{:cont, paths, []}
153127
end
154-
)
128+
129+
paths_to_sizes
130+
|> Stream.chunk_while(initial_state, chunk_fn, after_fn)
131+
|> Task.async_stream(
132+
fn chunk ->
133+
block_bytes = chunk |> Enum.map(&Map.get(path_to_size_map, &1)) |> Enum.sum()
134+
result = Enum.map(chunk, processor)
135+
on_update_progess.(block_bytes, "Indexing")
136+
result
137+
end,
138+
timeout: timeout
139+
)
140+
|> Stream.flat_map(fn
141+
{:ok, entry_chunks} -> entry_chunks
142+
_ -> []
143+
end)
144+
# The next bit is the only way i could figure out how to
145+
# call complete once the stream was realized
146+
|> Stream.transform(
147+
fn -> nil end,
148+
fn chunk_items, acc ->
149+
# By the chunk items list directly, each transformation
150+
# will flatten the resulting steam
151+
{chunk_items, acc}
152+
end,
153+
fn _acc ->
154+
on_complete.()
155+
end
156+
)
157+
else
158+
[]
159+
end
155160
end
156161

157162
defp path_to_sizes(paths) do

apps/remote_control/test/lexical/remote_control/search/indexer_test.exs

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
defmodule Lexical.RemoteControl.Search.IndexerTest do
22
alias Lexical.Project
3+
alias Lexical.RemoteControl.Dispatch
34
alias Lexical.RemoteControl.Search.Indexer
45
alias Lexical.RemoteControl.Search.Indexer.Entry
56

@@ -24,7 +25,7 @@ defmodule Lexical.RemoteControl.Search.IndexerTest do
2425

2526
setup do
2627
project = project()
27-
start_supervised(Lexical.RemoteControl.Dispatch)
28+
start_supervised(Dispatch)
2829
{:ok, project: project}
2930
end
3031

@@ -46,12 +47,8 @@ defmodule Lexical.RemoteControl.Search.IndexerTest do
4647

4748
@ephemeral_file_name "ephemeral.ex"
4849

49-
def with_an_ephemeral_file(%{project: project}) do
50+
def with_an_ephemeral_file(%{project: project}, file_contents) do
5051
file_path = Path.join([Project.root_path(project), "lib", @ephemeral_file_name])
51-
file_contents = ~s[
52-
defmodule Ephemeral do
53-
end
54-
]
5552
File.write!(file_path, file_contents)
5653

5754
on_exit(fn ->
@@ -61,6 +58,14 @@ defmodule Lexical.RemoteControl.Search.IndexerTest do
6158
{:ok, file_path: file_path}
6259
end
6360

61+
def with_a_file_with_a_module(context) do
62+
file_contents = ~s[
63+
defmodule Ephemeral do
64+
end
65+
]
66+
with_an_ephemeral_file(context, file_contents)
67+
end
68+
6469
def with_an_existing_index(%{project: project}) do
6570
{:ok, entry_stream} = Indexer.create_index(project)
6671
entries = Enum.to_list(entry_stream)
@@ -69,7 +74,7 @@ defmodule Lexical.RemoteControl.Search.IndexerTest do
6974
end
7075

7176
describe "update_index/2 encounters a new file" do
72-
setup [:with_an_existing_index, :with_an_ephemeral_file]
77+
setup [:with_an_existing_index, :with_a_file_with_a_module]
7378

7479
test "the ephemeral file is not previously present in the index", %{entries: entries} do
7580
refute Enum.any?(entries, fn entry -> Path.basename(entry.path) == @ephemeral_file_name end)
@@ -83,8 +88,31 @@ defmodule Lexical.RemoteControl.Search.IndexerTest do
8388
end
8489
end
8590

91+
def with_an_ephemeral_empty_file(context) do
92+
with_an_ephemeral_file(context, "")
93+
end
94+
95+
describe "update_index/2 encounters a zero-length file" do
96+
setup [:with_an_existing_index, :with_an_ephemeral_empty_file]
97+
98+
test "and does nothing", %{project: project} do
99+
{:ok, entry_stream, []} = Indexer.update_index(project, FakeBackend)
100+
assert [] = Enum.to_list(entry_stream)
101+
end
102+
103+
test "there is no progress", %{project: project} do
104+
# this ensures we don't emit progress with a total byte size of 0, which will
105+
# cause an ArithmeticError
106+
107+
Dispatch.register_listener(self(), :all)
108+
{:ok, entry_stream, []} = Indexer.update_index(project, FakeBackend)
109+
assert [] = Enum.to_list(entry_stream)
110+
refute_receive _
111+
end
112+
end
113+
86114
describe "update_index/2" do
87-
setup [:with_an_ephemeral_file, :with_an_existing_index]
115+
setup [:with_a_file_with_a_module, :with_an_existing_index]
88116

89117
test "sees the ephemeral file", %{entries: entries} do
90118
assert Enum.any?(entries, fn entry -> Path.basename(entry.path) == @ephemeral_file_name end)

0 commit comments

Comments
 (0)