Create a copy of the iterator before turning it into a stream
A functional language shouldn't modify the iterator, but instead keep advancing. As we can't stop in any particular point, we still just use a stream.
This commit is contained in:
@@ -9,15 +9,25 @@ defrecord Geef.Iterator, Record.extract(:geef_iterator, from: "src/geef_records.
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def new(iterator) do
|
||||||
def stream(iter = Iterator[]) do
|
set_elem(iterator, 0, Geef.Iterator)
|
||||||
&stream(iter, &1, &2)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def stream(iter = Iterator[type: ref], acc, fun) do
|
def stream!(Iterator[type: :ref, repo: repo, regexp: regexp]) do
|
||||||
|
iter =
|
||||||
|
case :geef_ref.iterator(repo, regexp) do
|
||||||
|
{:ok, iter} ->
|
||||||
|
Iterator.new iter
|
||||||
|
{:error, error} ->
|
||||||
|
raise Geef.IteratorError, message: error
|
||||||
|
end
|
||||||
|
&do_stream(iter, &1, &2)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_stream(iter = Iterator[type: :ref], acc, fun) do
|
||||||
case :geef_ref.next(rebind(iter)) do
|
case :geef_ref.next(rebind(iter)) do
|
||||||
{:ok, ref} ->
|
{:ok, ref} ->
|
||||||
stream(iter, fun.(Reference.new(ref), acc), fun)
|
do_stream(iter, fun.(Reference.new(ref), acc), fun)
|
||||||
{:error, :iterover} ->
|
{:error, :iterover} ->
|
||||||
acc
|
acc
|
||||||
{:error, error} ->
|
{:error, error} ->
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
-record(geef_request, {service :: atom(), path :: binary(), host :: binary()}).
|
-record(geef_request, {service :: atom(), path :: binary(), host :: binary()}).
|
||||||
-record(geef_tree_entry, {mode, type, id, name}).
|
-record(geef_tree_entry, {mode, type, id, name}).
|
||||||
-record(geef_signature, {name :: iolist(), email :: iolist(), time :: geef_time()}).
|
-record(geef_signature, {name :: iolist(), email :: iolist(), time :: geef_time()}).
|
||||||
-record(geef_iterator, {type :: atom(), handle}).
|
-record(geef_iterator, {type :: atom(), repo :: pid(), regexp :: iolist(), handle}).
|
||||||
|
|
||||||
-type geef_reference() :: #geef_reference{name :: binary(), target :: binary() | geef_oid()}.
|
-type geef_reference() :: #geef_reference{name :: binary(), target :: binary() | geef_oid()}.
|
||||||
-type geef_oid() :: #geef_oid{oid :: binary()}.
|
-type geef_oid() :: #geef_oid{oid :: binary()}.
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ lookup(Repo, Refname) ->
|
|||||||
iterator(Repo, Regexp) ->
|
iterator(Repo, Regexp) ->
|
||||||
case geef_repo:iterator(Repo, Regexp) of
|
case geef_repo:iterator(Repo, Regexp) of
|
||||||
{ok, Handle} ->
|
{ok, Handle} ->
|
||||||
{ok, #geef_iterator{type=ref, handle=Handle}};
|
{ok, #geef_iterator{type=ref, repo=Repo, regexp=Regexp, handle=Handle}};
|
||||||
Other ->
|
Other ->
|
||||||
Other
|
Other
|
||||||
end.
|
end.
|
||||||
|
|||||||
Reference in New Issue
Block a user