This is an automated email from the ASF dual-hosted git repository. davisp pushed a commit to branch prototype/views in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 6678306266a676bb4ebb57e3eaad32f403f0782e Author: Paul J. Davis <[email protected]> AuthorDate: Thu Jul 18 12:27:13 2019 -0500 Fix encoding layer for different key types We need to be able to selective use get_sort_key or not based on whether we're encoding the key for the key or value. Which makes no sense unless you remember we're storing two FDB rows for every view row. One is `(KeyWithSortKeys, OriginalKey)` and the second is `(KeyWithSortKeys, Value)`. There's a `Type` that I've elided that distinguishes between the two. --- src/couch_views/src/couch_views_encoding.erl | 85 ++++++++++++++-------------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/src/couch_views/src/couch_views_encoding.erl b/src/couch_views/src/couch_views_encoding.erl index 3af6d7f..9d3e3fc 100644 --- a/src/couch_views/src/couch_views_encoding.erl +++ b/src/couch_views/src/couch_views_encoding.erl @@ -15,65 +15,65 @@ -export([ encode/1, + encode/2, decode/1 ]). --define(NULL, 16#00). --define(FALSE, 16#26). --define(TRUE, 16#27). --define(NUMBER, 16#40). --define(STRING, 16#41). --define(LIST, 16#42). --define(OBJECT, 16#43). +-define(NULL, 0). +-define(FALSE, 1). +-define(TRUE, 2). +-define(NUMBER, 3). +-define(STRING, 4). +-define(LIST, 5). +-define(OBJECT, 6). encode(X) -> - Encoded = encode_int(X), - erlfdb_tuple:pack(Encoded). + encode_int(X, value). -decode(EncodedVal) -> - Val = erlfdb_tuple:unpack(EncodedVal), - decode_int(Val). +encode(X, Type) when Type == key; Type == value -> + erlfdb_tuple:pack(encode_int(X, value)) -encode_int(X) when is_atom(X) -> encode_atom(X); -encode_int(X) when is_number(X) -> encode_number(X); -encode_int(X) when is_binary(X) -> encode_binary(X); -encode_int(X) when is_list(X) -> encode_list(X); -encode_int(X) when is_tuple(X) -> encode_object(X). +decode(Encoded) -> + Val = erlfdb_tuple:unpack(Encoded), + decode_int(Val). -encode_atom(null) -> +encode_int(null, _Type) -> {?NULL}; -encode_atom(false) -> +encode_int(false, _Type) -> {?FALSE}; -encode_atom(true) -> - {?TRUE}. - - -encode_number(Val) -> - {?NUMBER, float(Val)}. +encode_int(true, _Type) -> + {?TRUE}; +encode_int(Num, key) when is_number(Num) -> + {?NUMBER, float(Num)}; -encode_binary(Val) -> - % TODO add sort strings - {?STRING, Val}. +encode_int(Num, value) when is_number(Num) -> + {?NUMBER, Num}; +encode_int(Bin, key) when is_binary(Bin) -> + {?STRING, couch_util:get_sort_key(Bin)}; -encode_list(List) -> - EncodedItems = lists:map(fun encode_int/1, List), - {?LIST, list_to_tuple(EncodedItems)}. +encode_int(Bin, value) when is_bianry(Bin) -> + {?STRING, Bin}; +encode_int(List, Type) when is_list(List) -> + Encoded = lists:map(fun(Item) -> + encode_int(Item, Type) + end, List), + {?LIST, list_to_tuple(Encoded)}; -encode_object({Props}) -> - EncodedProps = lists:map(fun({K, V}) -> - EncodedK = encode_int(K), - EncodedV = encode_int(V), - {EncodedK, EncodedV} +encode_int({Props}, Type) when is_list(Props) -> + Encoded = lists:map(fun({K, V}) -> + EK = encode_int(K, Type), + EV = encode_int(V, Type), + {EK, EV} end, Props), {?OBJECT, list_to_tuple(EncodedProps)}. @@ -87,20 +87,17 @@ decode_int({?FALSE}) -> decode_int({?TRUE}) -> true; -decode_int({?STRING, String}) -> - String; +decode_int({?STRING, Bin}) -> + Bin; -decode_int({?NUMBER, Number}) -> - case Number - trunc(Number) of - 0 -> trunc(Number); % convert to integer - _ -> Number - end; +decode_int({?NUMBER, Num}) -> + Num; decode_int({?LIST, List}) -> lists:map(fun decode_int/1, tuple_to_list(List)); decode_int({?OBJECT, Object}) -> - Props = lists:map(fun({EncodedK, EncodedV}) -> + Props = lists:map(fun({EK, EV}) -> K = decode_int(EncodedK), V = decode_int(EncodedV), {K, V}
