summaryrefslogtreecommitdiff
path: root/src/index.erl
diff options
context:
space:
mode:
authorMagnus Ahltorp <map@kth.se>2014-10-25 15:22:09 +0200
committerMagnus Ahltorp <map@kth.se>2014-10-25 15:22:09 +0200
commit2483f0cf09ccc4cf73558c7a85bbb51a72d29c3a (patch)
treed618ac06c64d92b5a350955391d5abd352563878 /src/index.erl
parent868a029e39ec8e9aa368da917146d088edee4d2f (diff)
Optimize db:get_by_indices by not fetching entry and implementing index:getrange
Diffstat (limited to 'src/index.erl')
-rw-r--r--src/index.erl41
1 files changed, 24 insertions, 17 deletions
diff --git a/src/index.erl b/src/index.erl
index 5169fbb..bbc9a10 100644
--- a/src/index.erl
+++ b/src/index.erl
@@ -12,7 +12,7 @@
%% TODO: Checksums
-module(index).
--export([get/2, add/3, addlast/2]).
+-export([get/2, getrange/3, add/3, addlast/2]).
-define(ENTRYSIZE, 32).
-define(ENTRYSIZEINFILE, (?ENTRYSIZE*2+1)).
@@ -66,31 +66,38 @@ add(Basepath, Index, Entry) when is_binary(Entry), size(Entry) == ?ENTRYSIZE ->
addlast(Basepath, Entry) ->
add(Basepath, last, Entry).
-%% From lib/stdlib/src/lists.erl. For supporting < R17.
--spec droplast(nonempty_list()) -> list().
-droplast([_T]) -> [];
-droplast([H|T]) -> [H|droplast(T)].
+decodedata(Binary) ->
+ lists:reverse(decodedata(Binary, [])).
-decodedata(EntryText) when length(EntryText) == ?ENTRYSIZEINFILE ->
- case [lists:last(EntryText)] of
- "\n" ->
- hex:hexstr_to_bin(droplast(EntryText));
- _ ->
- util:exit_with_error(badformat, readindex,
- "Index line not ending with linefeed")
- end.
+decodedata(<<>>, Acc) ->
+ Acc;
+decodedata(<<Entry:?ENTRYSIZE/binary-unit:16, "\n", Rest/binary>>, Acc) ->
+ decodedata(Rest, [mochihex:to_bin(binary_to_list(Entry)) | Acc]);
+decodedata(<<_:?ENTRYSIZE/binary-unit:16, _>>, _Acc) ->
+ util:exit_with_error(badformat, readindex,
+ "Index line not ending with linefeed").
-spec get(string(), integer()) -> binary().
get(Basepath, Index) ->
+ case getrange(Basepath, Index, Index) of
+ noentry ->
+ noentry;
+ [Entry] ->
+ Entry
+ end.
+
+-spec getrange(string(), integer(), integer()) -> [binary()].
+getrange(Basepath, Start, End) when Start =< End ->
case file:open(Basepath, [read, binary]) of
{ok, File} ->
{ok, Filesize} = file:position(File, eof),
if
- Index * ?ENTRYSIZEINFILE + ?ENTRYSIZEINFILE =< Filesize ->
+ End * ?ENTRYSIZEINFILE + ?ENTRYSIZEINFILE =< Filesize ->
{ok, _Position} = file:position(File,
- Index * ?ENTRYSIZEINFILE),
- {ok, EntryText} = file:read(File, ?ENTRYSIZEINFILE),
- Entry = decodedata(binary_to_list(EntryText)),
+ Start * ?ENTRYSIZEINFILE),
+ {ok, EntryText} =
+ file:read(File, ?ENTRYSIZEINFILE * (End - Start + 1)),
+ Entry = decodedata(EntryText),
file:close(File),
Entry;
true ->