Browse Source

swapped in the parallel find_all for the default implementation

pull/2/head
Sean Copenhaver 11 years ago
parent
commit
51b6949cb0
  1. 2
      Makefile
  2. 64
      lib/rope.ex

2
Makefile

@ -2,7 +2,7 @@
default: tags test default: tags test
all: tags test check docs all: tags test check graph perf docs
test: test:
mix test mix test

64
lib/rope.ex

@ -327,8 +327,8 @@ defmodule Rope do
end end
defrecordp :findctxt, defrecordp :findctxt,
findIndex: 0, #where the match started in the rope findIndex: 0 :: non_neg_integer, #where the match started in the rope
termIndex: 0 #next index to try termIndex: 0 :: non_neg_integer #next index to try
def find(rope, term) do def find(rope, term) do
termLen = String.length(term) termLen = String.length(term)
@ -374,24 +374,6 @@ defmodule Rope do
""" """
@spec find_all(rope, str) :: list(non_neg_integer) @spec find_all(rope, str) :: list(non_neg_integer)
def find_all(rope, term) do def find_all(rope, term) do
termLen = String.length(term)
foundMatch = fn(findctxt(termIndex: i)) -> i == termLen end
{_offset, possibles} = Enum.reduce(rope, { 0, []},
fn(rleaf(length: len, value: chunk), {offset, possibles}) ->
{offset + len, build_possible_matches(offset, chunk, term, possibles)}
end
)
match = possibles
|> Enum.filter(foundMatch)
|> Enum.map(fn(findctxt(findIndex: i)) -> i end)
|> Enum.reverse
end
def pfind_all(rope, term) do
termLength = String.length(term) termLength = String.length(term)
segments = partition_rope(0, rope, termLength, 0) segments = partition_rope(0, rope, termLength, 0)
parent = self() parent = self()
@ -402,7 +384,7 @@ defmodule Rope do
ref = make_ref ref = make_ref
spawn_link(fn() -> spawn_link(fn() ->
matches = Rope.find_all(slice, term) matches = do_find_all(slice, term)
|> Enum.map(fn(match) -> match + offset end) |> Enum.map(fn(match) -> match + offset end)
parent <- {ref, :pfind, self(), matches} parent <- {ref, :pfind, self(), matches}
@ -488,22 +470,29 @@ defmodule Rope do
end) end)
end end
defp partition_rope(offset, rleaf() = leaf, termLength, _depth) do
[{offset, Rope.length(leaf) + termLength}] defp partition_rope(_offset, nil, _termLength, _depth) do
[]
end end
defp partition_rope(offset, rnode(right: right, left: left) = node, termLength, depth) do defp partition_rope(offset, rleaf(length: len), termLength, _depth) do
[{offset, len + termLength}]
end
defp partition_rope(offset, rnode(length: len, right: right, left: left), termLength, depth) do
if offset > termLength do if offset > termLength do
offset = offset - termLength offset = offset - termLength
end end
cond do cond do
depth >= @partition_depth_limit -> depth >= @partition_depth_limit ->
[{offset, offset + Rope.length(node) + termLength}] [{offset, offset + len + termLength}]
Rope.length(left) <= @partition_size_threshold or Rope.length(right) <= @partition_size_threshold -> Rope.length(left) <= @partition_size_threshold or
[{offset, offset + Rope.length(node) + termLength}] Rope.length(right) <= @partition_size_threshold ->
(termLength / Rope.length(left)) > @partition_term_ratio or (termLength / Rope.length(right)) > @partition_term_ratio -> [{offset, offset + len + termLength}]
[{offset, offset + Rope.length(node) + termLength}] (termLength / Rope.length(left)) > @partition_term_ratio or
(termLength / Rope.length(right)) > @partition_term_ratio ->
[{offset, offset + len + termLength}]
true -> true ->
leftSegments = partition_rope(offset, left, termLength, depth + 1) leftSegments = partition_rope(offset, left, termLength, depth + 1)
rightSegments = partition_rope(offset + Rope.length(left), right, termLength, depth + 1) rightSegments = partition_rope(offset + Rope.length(left), right, termLength, depth + 1)
@ -512,6 +501,23 @@ defmodule Rope do
end end
end end
defp do_find_all(rope, term) do
termLen = String.length(term)
foundMatch = fn(findctxt(termIndex: i)) -> i == termLen end
{_offset, possibles} = Enum.reduce(rope, { 0, []},
fn(rleaf(length: len, value: chunk), {offset, possibles}) ->
{offset + len, build_possible_matches(offset, chunk, term, possibles)}
end
)
match = possibles
|> Enum.filter(foundMatch)
|> Enum.map(fn(findctxt(findIndex: i)) -> i end)
|> Enum.reverse
end
defp do_replace(rope, pattern, replacement) do defp do_replace(rope, pattern, replacement) do
termLen = String.length(pattern) termLen = String.length(pattern)
index = find(rope, pattern) index = find(rope, pattern)

Loading…
Cancel
Save