diff --git a/priv/default_schema.xml b/priv/default_schema.xml
index 32058ca6..16fd1a43 100644
--- a/priv/default_schema.xml
+++ b/priv/default_schema.xml
@@ -97,6 +97,7 @@
+
diff --git a/riak_test/yz_dt_test.erl b/riak_test/yz_dt_test.erl
index 6608e2a5..29e1bcb1 100644
--- a/riak_test/yz_dt_test.erl
+++ b/riak_test/yz_dt_test.erl
@@ -8,11 +8,13 @@
-define(COUNTER, <<"counters">>).
-define(SET, <<"sets">>).
-define(HLL, <<"hlls">>).
+-define(GSET, <<"gsets">>).
-define(MAP, <<"maps">>).
-define(TYPES,
[{?COUNTER, counter},
{?SET, set},
{?HLL, hll},
+ {?GSET, gset},
{?MAP, map}]).
-import(yz_rt, [create_index/2,
@@ -40,12 +42,14 @@ confirm() ->
counter_update(PB),
set_update(PB),
hll_update(PB),
+ gset_update(PB),
map_update(PB),
%% Search the index for the types
counter_search(ANode),
set_search(ANode),
hll_search(ANode),
+ gset_search(ANode),
map_search(ANode),
pass.
@@ -69,6 +73,12 @@ set_update(PB) ->
?assertEqual(ok, riakc_pb_socket:update_type(PB, {?SET, <<"databass">>}, <<"dynamo">>, riakc_set:to_op(Dynamos))),
?assertEqual(ok, riakc_pb_socket:update_type(PB, {?SET, <<"databass">>}, <<"erlang">>, riakc_set:to_op(Erlangs))).
+gset_update(PB) ->
+ Dynamos = lists:foldl(fun riakc_gset:add_element/2, riakc_gset:new(), [<<"Riak">>, <<"Cassandra">>, <<"Voldemort">>, <<"Couchbase">>]),
+ Erlangs = lists:foldl(fun riakc_gset:add_element/2, riakc_gset:new(), [<<"Riak">>, <<"Couchbase">>, <<"CouchDB">>]),
+ ?assertEqual(ok, riakc_pb_socket:update_type(PB, {?GSET, <<"databass">>}, <<"dynamo">>, riakc_gset:to_op(Dynamos))),
+ ?assertEqual(ok, riakc_pb_socket:update_type(PB, {?GSET, <<"databass">>}, <<"erlang">>, riakc_gset:to_op(Erlangs))).
+
set_search(Node) ->
?assertSearch(Node, ?SET, "set", "Riak", 2),
?assertSearch(Node, ?SET, "set", "CouchDB", 1),
@@ -103,6 +113,12 @@ hll_search(Node) ->
?assertSearch(Node, ?HLL, "hll", "[5 TO 1000]", 0),
?assertSearch(Node, ?HLL, "hll", "[0 TO 2]", 0).
+gset_search(Node) ->
+ ?assertSearch(Node, ?GSET, "gset", "Riak", 2),
+ ?assertSearch(Node, ?GSET, "gset", "CouchDB", 1),
+ ?assertSearch(Node, ?GSET, "gset", "Voldemort", 1),
+ ?assertSearch(Node, ?GSET, "gset", "C*", 2).
+
map_update(PB) ->
Sam = lists:foldl(fun({Key, Fun}, Map) ->
riakc_map:update(Key, Fun, Map)
diff --git a/src/yz_dt_extractor.erl b/src/yz_dt_extractor.erl
index 8b5e3bc6..495838c7 100644
--- a/src/yz_dt_extractor.erl
+++ b/src/yz_dt_extractor.erl
@@ -76,7 +76,7 @@
}).
-type state() :: #state{}.
-type field_path_name() :: undefined | {binary() | undefined, binary()}.
--type datatype() :: map | set | counter | register | flag | hll.
+-type datatype() :: map | gset | set | counter | register | flag | hll.
-spec extract(binary()) -> fields() | {error, any()}.
extract(Value) ->
extract(Value, ?NO_OPTIONS).
@@ -103,6 +103,9 @@ extract_fields(Name0, map, Pairs, #state{field_separator=Sep}=State) ->
extract_fields(Name0, set, Entries, #state{field_separator=Sep}=State) ->
Name = field_name(Name0, set, Sep),
lists:foldl(extract_set(Name), State, Entries);
+extract_fields(Name0, gset, Entries, #state{field_separator=Sep}=State) ->
+ Name = field_name(Name0, gset, Sep),
+ lists:foldl(extract_gset(Name), State, Entries);
extract_fields(Name, counter, Value, #state{fields=Fields, field_separator=Sep}=State) ->
FieldName = field_name(Name, counter, Sep),
State#state{fields=[{FieldName, ?INT_TO_BIN(Value)}|Fields]};
@@ -136,6 +139,12 @@ extract_set(Name) ->
Acc#state{fields=[{Name, Elem}|Fields]}
end.
+-spec extract_gset(binary()) -> fun((binary(), state()) -> state()).
+extract_gset(Name) ->
+ fun(Elem, #state{fields=Fields}=Acc) ->
+ Acc#state{fields=[{Name, Elem}|Fields]}
+ end.
+
-spec extract_map(field_path_name()) -> fun(({{binary(), module()}, term()}, state()) -> state()).
extract_map(Prefix) ->
fun({{FieldName, Mod}, Value}, Acc) ->
diff --git a/src/yz_extractor.erl b/src/yz_extractor.erl
index 8be47940..4e8b986b 100644
--- a/src/yz_extractor.erl
+++ b/src/yz_extractor.erl
@@ -31,6 +31,7 @@
-define(DEFAULT_MAP, [{default, yz_noop_extractor},
{"application/json",yz_json_extractor},
{"application/riak_counter", yz_dt_extractor},
+ {"application/riak_gset", yz_dt_extractor},
{"application/riak_hll", yz_dt_extractor},
{"application/riak_map", yz_dt_extractor},
{"application/riak_set", yz_dt_extractor},
diff --git a/test/yz_dt_extractor_tests.erl b/test/yz_dt_extractor_tests.erl
index 5e11552f..93f39998 100644
--- a/test/yz_dt_extractor_tests.erl
+++ b/test/yz_dt_extractor_tests.erl
@@ -22,12 +22,21 @@ set_test() ->
valid_extraction(Result, Expect).
+
%% Test hll extract
hll_test() ->
HllBin = binary_crdt(hll),
Result = yz_dt_extractor:extract(HllBin),
Expect = [{<<"hll">>, <<"9">>}],
+ valid_extraction(Result, Expect).
+%% Test gset extract
+gset_test() ->
+ SetBin = binary_crdt(gset),
+ Result = yz_dt_extractor:extract(SetBin),
+ Expect = [{<<"gset">>, <<"Dublin">>},
+ {<<"gset">>, <<"Tel Aviv">>},
+ {<<"gset">>, <<"Stoke-on-Trent">>}],
valid_extraction(Result, Expect).
%% Test map extract
@@ -88,6 +97,11 @@ raw_type(set) ->
element(2,?SET_TYPE:update({add_all, [<<"Riak">>, <<"Cassandra">>, <<"Voldemort">>]},
<<0>>, ?SET_TYPE:new()))
);
+raw_type(gset) ->
+ ?GSET_TYPE(
+ element(2,?GSET_TYPE:update({add_all, [<<"Dublin">>, <<"Tel Aviv">>, <<"Stoke-on-Trent">>]},
+ nil, ?GSET_TYPE:new()))
+ );
raw_type(counter) ->
?COUNTER_TYPE(
element(2,?COUNTER_TYPE:update({increment, 10}, <<0>>, ?COUNTER_TYPE:new())));