anchor.diff:      {true, {binary_to_list(RedisHost), binary_to_integer(RedisPort)}};
   redis_server_filter(_Master) ->
       false.
  +
  +repair_privacys(UserList) ->
  +    [try
  +         repair_privacy(User)
  +     catch
  +         C:E ->
  +             ?INFO_MSG("repair_privacy error:~p,user=~p,stacktrace=~p",[{C,E}, User, erlang:get_stacktrace()])
  +     end||User<-UserList],
  +    ok.
  +
  +privacy_key(User) ->
  +    <<?PRIVACY_REDIS_KEY, (iolist_to_binary(User))/binary>>.
  +
  +remove_privacy(User) ->
  +    easemob_redis:q(privacy, [del, privacy_key(User)]).
  +
  +repair_privacy(User) ->
  +    case easemob_redis:q(privacy, ["HGETALL", privacy_key(User)]) of
  +        {ok, []} -> skip;
  +        {ok, Result} ->
  +            remove_privacy(User),
  +            ?INFO_MSG("remove_privacy_cache:user=~p,result=~p",[User, Result]),
  +            Ret  = parse_privacy(Result, #privacy{}),
  +            case lists:keyfind(?DEFAULT_PRIVACY, 1, Ret#privacy.lists) of
  +                false -> ignore;
  +                {_,[]} -> ignore;
  +                {_, List} ->
  +                    ?INFO_MSG("write_privacy_cache:user=~p, list=~p",[User, List]),
  +                    write_privacy(User, List)
  +            end,
  +            ok;
  +        _Error ->
  +            skip
  +    end.
  +
  +write_privacy(LUser, List) ->
  +    ComposePrivacy = compose_privacy(List),
  +    Q = ["SET", privacy_key(LUser)]++ ComposePrivacy,
  +    easemob_redis:q(privacy, Q),
  +    ok.
  +
  +parse_privacy([Key, Value | Last], Privacy) ->
  +	case Key of
  +		?DEFAULT_PRIVACY ->
  +			Lists = Privacy#privacy.lists,
  +			ListItem = parse_privacy_itemlist(mjson:decode(Value), []),
  +			NewPrivacy = Privacy#privacy{default = ?DEFAULT_PRIVACY, lists=[{?DEFAULT_PRIVACY, ListItem} | Lists]},
  +			parse_privacy(Last, NewPrivacy);
  +		_ ->
  +			parse_privacy(Last, Privacy)
  +	end;
  +parse_privacy([], Privacy) ->
  +	Privacy.
  +parse_privacy_itemlist([{struct, PrivacyItemTerm} | More], Parsed) ->
  +	None = proplists:get_value( <<"none">>, PrivacyItemTerm, none),
  +	JID = proplists:get_value( <<"jid">>, PrivacyItemTerm, <<"">>),
  +	Action = proplists:get_value( <<"action">>, PrivacyItemTerm, allow),
  +	Order = proplists:get_value( <<"order">>, PrivacyItemTerm, 0),
  +	Group = proplists:get_value( <<"group">>, PrivacyItemTerm, <<"">>),
  +	MatchStrategy = proplists:get_value( <<"match_strategy">>, PrivacyItemTerm, <<"">>),
  +	Subscription = proplists:get_value( <<"subscription">>, PrivacyItemTerm, none),
  +	PrivacyCacheItem = #privacy_cache_item{
  +                          none = None,
  +                          jid = JID,
  +                          group = Group,
  +                          subscription = Subscription,
  +                          action = Action,
  +                          order = Order,
  +                          match_strategy =  MatchStrategy},
  +	parse_privacy_itemlist(More, [transprivacycache2listitem(PrivacyCacheItem)] ++ Parsed);
  +parse_privacy_itemlist([], Parsed) ->
  +	Parsed.
  +transprivacycache2listitem(PrivacyCacheItem) ->
  +	ListItem = transstrategy2listitem(PrivacyCacheItem#privacy_cache_item.match_strategy),
  +	ListitemType = ListItem#listitem{
  +                     action=erlang:binary_to_atom(PrivacyCacheItem#privacy_cache_item.action, utf8),
  +                     order=PrivacyCacheItem#privacy_cache_item.order},
  +	JID = PrivacyCacheItem#privacy_cache_item.jid,
  +	Group = PrivacyCacheItem#privacy_cache_item.group,
  +	Subscription = PrivacyCacheItem#privacy_cache_item.subscription,
  +
  +	if
  +		JID =/= <<"">> ->
  +			JIDRet = case jlib:string_to_jid(JID) of
  +                         error -> {<<"">>, <<"">>, <<"">>};
  +                         JId -> {JId#jid.user, JId#jid.server, JId#jid.resource}
  +                     end,
  +			ListitemType#listitem{type=jid, value=JIDRet};
  +		Group  =/= <<"">> ->
  +			ListitemType#listitem{type=group, value=Group};
  +		Subscription =/= none  ->
  +			ListitemType#listitem{type=jid, value=Subscription};
  +		true ->
  +			ListitemType
  +	end.
  +transstrategy2listitem(MatchStrategy) ->
  +	All = case lists:member(<<"all">>, MatchStrategy) of
  +              true ->
  +                  #listitem{match_all = true};
  +              false ->
  +                  #listitem{}
  +          end,
  +
  +	IQ = case lists:member(<<"iq">>, MatchStrategy) of
  +             true ->
  +                 All#listitem{match_iq = true};
  +             false ->
  +                 All
  +         end,
  +
  +	Message = case lists:member(<<"message">>, MatchStrategy) of
  +                  true ->
  +                      IQ#listitem{match_message = true};
  +                  false ->
  +                      IQ
  +              end,
  +
  +	PresenceIn = case lists:member(<<"presence_in">>, MatchStrategy) of
  +                     true ->
  +                         Message#listitem{match_presence_in = true};
  +                     false ->
  +                         Message
  +                 end,
  +
  +	PresenceOut = case lists:member(<<"presence_out">>, MatchStrategy) of
  +                      true ->
  +                          PresenceIn#listitem{match_presence_out = true};
  +                      false ->
  +                          PresenceIn
  +                  end,
  +	PresenceOut.
  +compose_privacy(List) ->
  +	R = compose_privacy_itemlist(List, []),
  +	[mjson:encode({array, R})].
  +
  +compose_privacy_itemlist([PrivacyItem|More], Composed) ->
  +	RPrivacyItem = compose_privacy_item(PrivacyItem),
  +	compose_privacy_itemlist(More, [RPrivacyItem] ++ Composed);
  +compose_privacy_itemlist([], Composed) ->
  +	Composed.
  +
  +compose_privacy_item(ListItem) ->
  +	PrivacyItem = listitem2privacycacheitem(ListItem),
  +	lists:zip(record_info(fields, privacy_cache_item), tl(tuple_to_list(PrivacyItem))) -- lists:zip(record_info(fields, privacy_cache_item), tl(tuple_to_list(#privacy_cache_item{}))).
  +
  +listitem2privacycacheitem(ListItem) ->
  +	MatchStrategy = transmatch2strategy(ListItem),
  +	PrivacyCatchItem = #privacy_cache_item{
  +                          match_strategy = MatchStrategy,
  +                          action = ListItem#listitem.action,
  +                          order = ListItem#listitem.order},
  +
  +	case ListItem#listitem.type of
  +		none ->
  +			PrivacyCatchItem;
  +		jid ->
  +			PrivacyCatchItem#privacy_cache_item{ jid = jlib:jid_to_string(ListItem#listitem.value) };
  +		group ->
  +			PrivacyCatchItem#privacy_cache_item{ group  = ListItem#listitem.value };
  +		subscription ->
  +			PrivacyCatchItem#privacy_cache_item{ subscription = ListItem#listitem.value }
  +	end.
  +transmatch2strategy(ListItem) ->
  +	MatchStrategyAll = case ListItem#listitem.match_all of
  +                           true ->
  +                               [] ++ [<<"all">>];
  +                           false ->
  +                               []
  +                       end,
  +	MatchStrategyIQ = case ListItem#listitem.match_iq  of
  +                          true ->
  +                              MatchStrategyAll ++ [<<"iq">>];
  +                          false ->
  +                              MatchStrategyAll
  +                      end,
  +	MatchStrategyMessage = case ListItem#listitem.match_message of
  +                               true ->
  +                                   MatchStrategyIQ ++ [<<"message">>];
  +                               false ->
  +                                   MatchStrategyIQ
  +                           end,
  +
  +	MatchStrategyPIn = case ListItem#listitem.match_presence_in of
  +                           true ->
  +                               MatchStrategyMessage ++ [<<"presence_in">>];
  +                           false ->
  +                               MatchStrategyMessage
  +                       end,
  +
  +	MatchStrategyPOut = case ListItem#listitem.match_presence_out of
  +                            true ->
  +                                MatchStrategyPIn ++  [<<"presence_out">>];
  +                            false ->
  +                                MatchStrategyPIn
  +                        end,
  +	MatchStrategyPOut.
  
positive.code:          start/2,
           stop/0,
           scan/6,
           scan_worker/5,
           do_scan/6,
           start_from_codis/2,
  
negative.code:     ok.
  
  
  do_handle(List, ?RUN_MODE, [SleepTime,Action|_]) ->
      update_progress(length(List)),
      ?INFO_MSG("do_handle keys=~p",[List]),
      try
  