Implement ref iterators

This commit is contained in:
Carlos Martín Nieto
2013-08-09 23:25:55 +02:00
parent 6e24413388
commit bb35fce5cc
9 changed files with 161 additions and 4 deletions

View File

@@ -4,6 +4,8 @@
-module(geef_nif).
-compile(export_all).
-include("geef_records.hrl").
-on_load(load_enif/0).
-define(NIF_FN, nif_error(?LINE)).
@@ -50,6 +52,14 @@ reference_glob(_Repo, _Glob) ->
reference_lookup(_Repo, _Refname) ->
nif_error(?LINE).
-spec reference_iterator(term(), iolist() | undefined) -> {ok, geef_iterator()} | {error, term()}.
reference_iterator(_Repo, _Regexp) ->
nif_error(?LINE).
-spec reference_next(geef_iterator()) -> {ok, term()} | {error, iterover | term()}.
reference_next(_Handle) ->
nif_error(?LINE).
reference_target(_Handle) ->
nif_error(?LINE).

View File

@@ -13,6 +13,7 @@
-record(geef_request, {service :: atom(), path :: binary(), host :: binary()}).
-record(geef_tree_entry, {mode, type, id, name}).
-record(geef_signature, {name :: iolist(), email :: iolist(), time :: geef_time()}).
-record(geef_iterator, {type :: atom(), handle}).
-type geef_reference() :: #geef_reference{name :: binary(), target :: binary() | geef_oid()}.
-type geef_oid() :: #geef_oid{oid :: binary()}.
@@ -22,3 +23,4 @@
-type geef_tree_entry() :: #geef_tree_entry{}.
-type geef_signature() :: #geef_signature{}.
-type geef_time() :: {erlang:timestamp(), non_neg_integer()}.
-type geef_iterator() :: #geef_iterator{}.

View File

@@ -1,6 +1,6 @@
-module(geef_ref).
-export([lookup/2, resolve/1, create/4, dwim/2, shorthand/1]).
-export([lookup/2, iterator/1, iterator/2, next/1, resolve/1, create/4, dwim/2, shorthand/1]).
-include("geef_records.hrl").
@@ -35,6 +35,28 @@ lookup(Repo, Refname) ->
Other
end.
-spec iterator(pid(), iolist() | undefined) -> {ok, geef_iterator()} | {error, term()}.
iterator(Repo, Regexp) ->
case geef_repo:iterator(Repo, Regexp) of
{ok, Handle} ->
{ok, #geef_iterator{type=ref, handle=Handle}};
Other ->
Other
end.
-spec iterator(pid()) -> {ok, geef_iterator()} | {error, term()}.
iterator(Repo) ->
iterator(Repo, undefined).
next(#geef_iterator{type=ref, handle=Handle}) ->
case geef_nif:reference_next(Handle) of
{ok, RefHandle} ->
{ok, Name} = geef_nif:reference_name(RefHandle),
{ok, new(Name, RefHandle)};
Other ->
Other
end.
-spec resolve(geef_reference()) -> {ok, geef_reference()} | {error, term()}.
resolve(Ref = #geef_reference{type=oid}) ->
{ok, Ref}; % resolving an oid ref is a no-op, skip going into the NIF

View File

@@ -17,7 +17,7 @@
%% API
-export([open/1, init/2, path/1, workdir/1, odb/1, is_bare/1, references/1, discover/1,
lookup_object/2, lookup_reference/2, create_reference/4, revwalk/1, stop/1,
reference_dwim/2, handle/1]).
reference_dwim/2, handle/1, iterator/2]).
-include("geef_records.hrl").
-record(state, {handle}).
@@ -86,6 +86,11 @@ lookup_object(Pid, Oid) ->
lookup_reference(Pid, Name) ->
gen_server:call(Pid, {lookup_reference, Name}).
%% @private
-spec iterator(pid(), iolist() | undefined) -> {ok, geef_iterator()} | {error, term()}.
iterator(Pid, Regexp) ->
gen_server:call(Pid, {iterator, Regexp}).
%% @private
reference_dwim(Pid, Name) ->
gen_server:call(Pid, {dwim_reference, Name}).
@@ -136,6 +141,9 @@ handle_call({lookup_object, Oid}, _From, State = #state{handle=Handle}) ->
handle_call({lookup_reference, Name}, _From, State = #state{handle=Handle}) ->
Reply = geef_nif:reference_lookup(Handle, Name),
{reply, Reply, State};
handle_call({iterator, Regexp}, _From, State = #state{handle=Handle}) ->
Reply = geef_nif:reference_iterator(Handle, Regexp),
{reply, Reply, State};
handle_call({dwim_reference, Name}, _From, State = #state{handle=Handle}) ->
Reply = geef_nif:reference_dwim(Handle, Name),
{reply, Reply, State};