You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2019/07/23 20:13:20 UTC

[couchdb] 11/25: Fix encoding layer for different key types

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 <pa...@gmail.com>
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}