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
all: tags test check docs
all: tags test check graph perf docs
test:
mix test

64
lib/rope.ex

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

Loading…
Cancel
Save