You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ei...@apache.org on 2020/02/11 16:32:18 UTC
[couchdb] 03/04: Use flattened JSON for store doc in fdb
This is an automated email from the ASF dual-hosted git repository.
eiri pushed a commit to branch prototype/flattened-doc-storage
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 999686e76b924c8a9f44bdcc528b6252c914ff92
Author: Eric Avdey <ei...@eiri.ca>
AuthorDate: Mon Feb 10 17:39:07 2020 -0400
Use flattened JSON for store doc in fdb
---
src/fabric/src/fabric2_fdb.erl | 74 ++++++++++++++++++++++++++++++------------
1 file changed, 53 insertions(+), 21 deletions(-)
diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl
index 6abe1f6..cdd1b60 100644
--- a/src/fabric/src/fabric2_fdb.erl
+++ b/src/fabric/src/fabric2_fdb.erl
@@ -508,18 +508,15 @@ get_doc_body_future(#{} = Db, DocId, RevInfo) ->
db_prefix := DbPrefix
} = ensure_current(Db),
- #{
- rev_id := {RevPos, Rev}
- } = RevInfo,
-
- Key = {?DB_DOCS, DocId, RevPos, Rev},
+ Key = {?DB_DOCS, DocId},
{StartKey, EndKey} = erlfdb_tuple:range(Key, DbPrefix),
erlfdb:fold_range_future(Tx, StartKey, EndKey, []).
get_doc_body_wait(#{} = Db0, DocId, RevInfo, Future) ->
#{
- tx := Tx
+ tx := Tx,
+ db_prefix := DbPrefix
} = Db = ensure_current(Db0),
#{
@@ -527,12 +524,22 @@ get_doc_body_wait(#{} = Db0, DocId, RevInfo, Future) ->
rev_path := RevPath
} = RevInfo,
- RevBodyRows = erlfdb:fold_range_wait(Tx, Future, fun({_K, V}, Acc) ->
- [V | Acc]
+ DocPrefix = erlfdb_tuple:pack({?DB_DOCS, DocId}, DbPrefix),
+
+ MetaBodyAcc = erlfdb:fold_range_wait(Tx, Future, fun({K, V}, Acc) ->
+ Tuple = erlfdb_tuple:unpack(K, DocPrefix),
+ case tuple_to_list(Tuple) of
+ [Deleted, RevPos, Rev] ->
+ {[], V, Deleted};
+ [_Deleted, RevPos, Rev | KeyPath] ->
+ {Body, DiskAtts, Deleted} = Acc,
+ {[{KeyPath, V} | Body], DiskAtts, Deleted};
+ _ ->
+ Acc
+ end
end, []),
- BodyRows = lists:reverse(RevBodyRows),
- fdb_to_doc(Db, DocId, RevPos, [Rev | RevPath], BodyRows).
+ fdb_to_doc(Db, DocId, RevPos, [Rev | RevPath], MetaBodyAcc).
get_local_doc(#{} = Db0, <<?LOCAL_DOC_PREFIX, _/binary>> = DocId) ->
@@ -1041,10 +1048,11 @@ clear_doc_body(#{} = Db, DocId, #{} = RevInfo) ->
} = Db,
#{
- rev_id := {RevPos, Rev}
+ rev_id := {RevPos, Rev},
+ deleted := Deleted
} = RevInfo,
- BaseKey = {?DB_DOCS, DocId, RevPos, Rev},
+ BaseKey = {?DB_DOCS, DocId, Deleted, RevPos, Rev},
{StartKey, EndKey} = erlfdb_tuple:range(BaseKey, DbPrefix),
ok = erlfdb:clear_range(Tx, StartKey, EndKey).
@@ -1182,21 +1190,33 @@ doc_to_fdb(Db, #doc{} = Doc) ->
DiskAtts = lists:map(fun couch_att:to_disk_term/1, Atts),
- Value = term_to_binary({Body, DiskAtts, Deleted}, [{minor_version, 1}]),
+ DocKey = {?DB_DOCS, Id, Deleted, Start, Rev},
+ DocPrefix = erlfdb_tuple:pack(DocKey, DbPrefix),
+ Meta = term_to_binary(DiskAtts, [{minor_version, 1}]),
+ Rows0 = [{DocPrefix, Meta}],
- {Rows, _} = lists:mapfoldl(fun(Chunk, ChunkId) ->
- Key = erlfdb_tuple:pack({?DB_DOCS, Id, Start, Rev, ChunkId}, DbPrefix),
- {{Key, Chunk}, ChunkId + 1}
- end, 0, chunkify_binary(Value)),
- Rows.
+ Body1 = case Body of
+ {[]} -> [];
+ _ -> couch_util:json_explode(Body)
+ end,
+ lists:foldl(fun({K, V}, Acc) ->
+ Key = erlfdb_tuple:pack(list_to_tuple(K), DocPrefix),
+ Value = encode_body_value(V),
+ [{Key, Value} | Acc]
+ end, Rows0, Body1).
fdb_to_doc(_Db, _DocId, _Pos, _Path, []) ->
{not_found, missing};
-fdb_to_doc(Db, DocId, Pos, Path, BinRows) when is_list(BinRows) ->
- Bin = iolist_to_binary(BinRows),
- {Body, DiskAtts, Deleted} = binary_to_term(Bin, [safe]),
+fdb_to_doc(Db, DocId, Pos, Path, MetaBodyAcc) ->
+ {Body0, DiskAtts0, Deleted} = MetaBodyAcc,
+ BodyRows = [{K, decode_body_value(V)} || {K, V} <- lists:reverse(Body0)],
+ Body = case BodyRows of
+ [] -> {[]};
+ _ -> couch_util:json_implode(BodyRows)
+ end,
+ DiskAtts = binary_to_term(DiskAtts0, [safe]),
Atts = lists:map(fun(Att) ->
couch_att:from_disk_term(Db, DocId, Att)
end, DiskAtts),
@@ -1214,6 +1234,18 @@ fdb_to_doc(Db, DocId, Pos, Path, BinRows) when is_list(BinRows) ->
end.
+encode_body_value(V) when is_list(V); is_tuple(V) ->
+ term_to_binary(V, [{minor_version, 1}]);
+encode_body_value(V) ->
+ erlfdb_tuple:pack({V}).
+
+decode_body_value(<<131, _/binary>> = V) ->
+ binary_to_term(V, [safe]);
+decode_body_value(V) ->
+ {V1} = erlfdb_tuple:unpack(V),
+ V1.
+
+
local_doc_to_fdb(Db, #doc{} = Doc) ->
#{
db_prefix := DbPrefix