Просмотр исходного кода

feat(map_lib): add emqx_map_lib:diff_maps/2

Shawn 4 лет назад
Родитель
Сommit
e6306bccd8
1 измененных файлов с 22 добавлено и 0 удалено
  1. 22 0
      apps/emqx/src/emqx_map_lib.erl

+ 22 - 0
apps/emqx/src/emqx_map_lib.erl

@@ -27,6 +27,7 @@
         , jsonable_map/2
         , binary_string/1
         , deep_convert/3
+        , diff_maps/2
         ]).
 
 -export_type([config_key/0, config_key_path/0]).
@@ -129,6 +130,27 @@ jsonable_map(Map) ->
 jsonable_map(Map, JsonableFun) ->
     deep_convert(Map, fun binary_string_kv/3, [JsonableFun]).
 
+-spec diff_maps(map(), map()) ->
+    #{added := [map()], identical := [map()], removed := [map()],
+      changed := [#{any() => {OldValue::any(), NewValue::any()}}]}.
+diff_maps(NewMap, OldMap) ->
+    InitR = #{identical => [], changed => [], removed => []},
+    {Result, RemInNew} =
+        lists:foldl(fun({OldK, OldV}, {Result0 = #{identical := I, changed := U, removed := D},
+                        RemNewMap}) ->
+            Result1 = case maps:find(OldK, NewMap) of
+                error ->
+                    Result0#{removed => [#{OldK => OldV} | D]};
+                {ok, NewV} when NewV == OldV ->
+                    Result0#{identical => [#{OldK => OldV} | I]};
+                {ok, NewV} ->
+                    Result0#{changed => [#{OldK => {OldV, NewV}} | U]}
+            end,
+            {Result1, maps:remove(OldK, RemNewMap)}
+        end, {InitR, NewMap}, maps:to_list(OldMap)),
+    Result#{added => RemInNew}.
+
+
 binary_string_kv(K, V, JsonableFun) ->
     case JsonableFun(K, V) of
         drop -> drop;