Browse Source

match keys

dxt 2 years ago
parent
commit
93cb797ef7
8 changed files with 39 additions and 11 deletions
  1. 2 1
      include/backend.hrl
  2. 1 1
      mix.exs
  3. 8 1
      src/kvs.erl
  4. 1 0
      src/stores/kvs_fs.erl
  5. 2 0
      src/stores/kvs_mnesia.erl
  6. 17 0
      src/stores/kvs_rocks.erl
  7. 5 5
      test/fd_test.exs
  8. 3 3
      test/st_test.exs

+ 2 - 1
include/backend.hrl

@@ -1,7 +1,8 @@
 -ifndef(BACKEND_HRL).
 -define(BACKEND_HRL, true).
 -define(BACKEND, [db/0,get/3,put/1,put/2,delete/3,delete_range/3,index/3,dump/0,start/0,stop/0,destroy/0,destroy/1,keys/2,
-                  join/2,leave/0,leave/1,dir/0,create_table/2,add_table_index/2,seq/2,all/2,count/1,version/0,match/1,index_match/2]).
+                  join/2,leave/0,leave/1,dir/0,create_table/2,add_table_index/2,seq/2,all/2,count/1,version/0,
+                  match/1,match/3,index_match/2]).
 -compile({no_auto_import,[get/1,put/2]}).
 -include("kvs.hrl").
 -spec put(tuple() | list(tuple())) -> ok | {error,any()}.

+ 1 - 1
mix.exs

@@ -4,7 +4,7 @@ defmodule KVS.Mixfile do
   def project do
     [
       app: :kvs,
-      version: "9.9.0",
+      version: "9.9.1",
       description: "KVS Abstract Chain Database",
       package: package(),
       deps: deps()

+ 8 - 1
src/kvs.erl

@@ -25,6 +25,7 @@
          ensure/2,
          seq_gen/0,
          keys/1,
+         find/2,
          fields/1,
          defined/2,
          field/2,
@@ -74,9 +75,12 @@ get(Table, Key) ->
 index(Table, K, V) ->
     index(Table, K, V, #kvs{mod = dba()}).
 
-keys(Feed) -> 
+keys(Feed) ->
     keys(Feed, #kvs{mod = dba(), db = db()}).
 
+find(Feed, Id) ->
+  find(Feed,Id, #kvs{mod = dba(), db=db()}).
+
 match(Record) ->
     match(Record, #kvs{mod = dba()}).
 
@@ -135,6 +139,9 @@ index(Tab, Key, Value, #kvs{mod = DBA}) ->
 keys(Feed, #kvs{mod = DBA, db = Db}) ->
     DBA:keys(Feed, Db).
 
+find(Feed, Id, #kvs{mod = DBA, db = Db}) ->
+    DBA:find(Feed, Id, Db).
+
 match(Record, #kvs{mod = DBA}) ->
     DBA:match(Record).
 

+ 1 - 0
src/stores/kvs_fs.erl

@@ -77,6 +77,7 @@ delete(TableName, Key, _) ->
     end.
 delete_range(_,_,_) -> {error, not_found}.
 keys(_,_) -> [].
+match(_,_,_) -> [].
 
 count(RecordName) -> length(filelib:fold_files(filename:join([dir_name(), RecordName]), "",true, fun(A,Acc)-> [A|Acc] end, [])).
 

+ 2 - 0
src/stores/kvs_mnesia.erl

@@ -38,6 +38,8 @@ index(Tab,Key,Value) ->
 
 keys(Tab,_) -> mnesia:all_keys(Tab).
 
+match(_Tab,_Id,_) -> [].
+
 get(RecordName, Key, _) -> just_one(fun() -> mnesia:read(RecordName, Key) end).
 put(R)                  -> put(R,db()).
 put(Records, _) when is_list(Records) -> void(fun() -> lists:foreach(fun mnesia:write/1, Records) end);

+ 17 - 0
src/stores/kvs_rocks.erl

@@ -39,6 +39,23 @@ keys(Tab, Db) ->
     {ok, K, _} = rocksdb:iterator_move(H, {seek, Feed}),
     Keys(K,[]).
 
+ match(Tab, Id, Db) ->
+  Feed = key(Tab,[]),
+  {ok, H} = rocksdb:iterator(ref(Db), []),
+  Keys = fun KEY(K1) when 
+              binary_part(K1,{0,byte_size(Feed)}) =:= Feed andalso
+              binary_part(K1,{byte_size(K1), -byte_size(Id)}) =:= Id ->
+              rocksdb:iterator_close(H), [K1];
+             KEY(K1) when binary_part(K1,{0,byte_size(Feed)}) =:= Feed ->
+                case rocksdb:iterator_move(H, next) of
+                  {ok,K2,_} -> KEY(K2);
+                          _ -> []
+                end;
+             KEY(_) -> rocksdb:iterator_close(H), []
+         end,
+  {ok, K, _} = rocksdb:iterator_move(H, {seek, Feed}),
+  Keys(K).
+
 fmt([]) -> [];
 fmt(K) -> Key = tb(K),
   End = sz(Key),

+ 5 - 5
test/fd_test.exs

@@ -91,10 +91,10 @@ defmodule Fd.Test do
             end)
         r = :kvs.load_reader(rid)
         assert r = :kvs.prev(r)
-        assert r = KVS.reader(:kvs.prev(:kvs.top(r)), args: [])                 
+        assert r = KVS.reader(:kvs.prev(:kvs.top(r)), args: [])
     end
 
-    test "prev to empty" do        
+    test "prev to empty" do
         :lists.map(fn _ -> :kvs.append(msg(id: :kvs.seq([],[])), "/aco") end, :lists.seq(1,2))
         all = :kvs.all("/aco")
         head = Enum.at(all,0)
@@ -152,17 +152,17 @@ defmodule Fd.Test do
 
     test "corrupted writers doesn't affect all" do
         prev = :kvs.all("/crm/duck")
-        
+
         KVS.writer(cache: ch) = w = :kvs.writer("/crm/duck")
         w1 = KVS.writer(w, cache: {:msg, "unknown", "/corrupted"})
-        
+
         :ok = :kvs_rocks.put(w1)
         w2 = :kvs.writer("/crm/duck")
         assert {:ok, ^w2} = :kvs.get(:writer, "/crm/duck")
         assert w1 == w2
 
         assert prev = :kvs.all("/crm/duck")
-        
+
         {:ok,_} = :kvs.get(:writer, "/crm/duck")
         :ok = :kvs.delete(:writer, "/crm/duck")
         {:error, :not_found} = :kvs.get(:writer, "/crm/duck")

+ 3 - 3
test/st_test.exs

@@ -38,7 +38,7 @@ defmodule St.Test do
 
         assert KVS.reader(id: ^rid, feed: ^feed, args: []) = :kvs.take(KVS.reader(r, args: 0, dir: 0))
         assert KVS.reader(id: ^rid, feed: ^feed, args: []) = :kvs.take(KVS.reader(r, args: -1, dir: 0))
-        
+
         assert r1 = KVS.reader(id: ^rid, feed: ^feed, args: a01) = :kvs.take(KVS.reader(r,  args: 10, dir: 0))
         assert kvs[:id2] |> Enum.map(&msg(id: &1)) == a01
         assert KVS.reader(id: ^rid, feed: ^feed, args: []) = :kvs.take(KVS.reader(r1, args: 10, dir: 0))
@@ -68,7 +68,7 @@ defmodule St.Test do
         assert KVS.reader(id: ^rid, feed: ^feed, args: ^tpm, dir: 1) = :kvs.take(KVS.reader(r, args: 100, dir: 1))
 
         assert r1 = KVS.reader(feed: ^feed, count: 10, args: [], cache: {:msg,^bot,^feed}) = :kvs.bot(r)
-        
+
         assert r2 = KVS.reader(feed: ^feed, count: 10, args: a01) = :kvs.take(KVS.reader(r1, args: 5, dir: 1))
         x01 = Enum.drop(kvs[:id1],5) |> Enum.map(&msg(id: &1)) |> Enum.reverse
         assert x01 == a01
@@ -114,7 +114,7 @@ defmodule St.Test do
         assert :kvs.feed("/crm/personal/Реєстратор А1/in/directory/duck") 
             ++ :kvs.feed("/crm/personal/Реєстратор А1/in/doc")
             ++ :kvs.feed("/crm/personal/Реєстратор А1/in/mail") == :kvs.feed("/crm/personal/Реєстратор А1/in")
-    end 
+    end
 
     defp log(x), do: IO.puts '#{inspect(x)}'
     defp log(m, x), do: IO.puts '#{m} #{inspect(x)}'