anchor.diff:          _ -> 0
       end.
   
  -
  -%% While Pid is alive prevents autocompaction of views for given
  -%% bucket and given node. Returned Ref can be used to uninhibit
  -%% autocompaction.
  -%%
  -%% If views of given bucket are being compacted right now, it'll wait
  -%% for end of compaction rather than aborting it.
  -%%
  -%% Attempt to inhibit already inhibited compaction will result in nack.
  -%%
  -%% Note: we assume that caller of both inhibit_view_compaction and
  -%% uninhibit_view_compaction is somehow related to Pid and will die
  -%% automagically if Pid dies, because autocompaction daemon may
  -%% actually forget about this calls.
  --spec inhibit_view_compaction(bucket_name(), node(), pid()) ->
  -                                     {ok, reference()} | nack.
  -inhibit_view_compaction(Bucket, Node, Pid) ->
  -    gen_fsm:sync_send_all_state_event({?MODULE, Node},
  -                                      {inhibit_view_compaction, list_to_binary(Bucket), Pid},
  -                                      infinity).
  -
  -
  -%% Using Ref returned from inhibit_view_compaction undoes it's
  -%% effect. It'll also consider kicking views autocompaction for given
  -%% bucket asap. And it's do it _before_ replying.
  --spec uninhibit_view_compaction(bucket_name(), node(), reference()) -> ok | nack.
  -uninhibit_view_compaction(Bucket, Node, Ref) ->
  -    gen_fsm:sync_send_all_state_event({?MODULE, Node},
  -                                      {uninhibit_view_compaction, list_to_binary(Bucket), Ref},
  -                                      infinity).
  -
  -%% gen_fsm callbacks
  +%% gen_server callbacks
   init([]) ->
       process_flag(trap_exit, true),
   
  
positive.code:     %% should not happen
      exit({invalid_period_key_bug, OtherKey}).
  
  -spec check_period(#config{}) -> ok.
  check_period(#config{allowed_period=undefined}) ->
      ok;
  check_period(#config{allowed_period=Period}) ->
      do_check_period(Period).
  
  do_check_period(#period{from_hour=FromHour,
                          from_minute=FromMinute,
                          to_hour=ToHour,
                          to_minute=ToMinute,
                          abort_outside=AbortOutside}) ->
      {HH, MM, _} = erlang:time(),
  
      Now0 = time_to_minutes(HH, MM),
  
negative.code:                     end
              end,
  
              {noreply, unregister_forced_compaction(Pid, State)};
          error ->
              ?log_error("Unexpected process termination ~p: ~p. Dying.",
                         [Pid, Reason]),
              {stop, Reason, State}
      end;
  handle_info(config_changed,
              #state{kv_compaction = KVCompaction,
                     views_compaction = ViewsCompaction} = State) ->
      misc:flush(config_changed),
      Config = ns_config:get(),
  
      {noreply, State#state{kv_compaction = process_config_change(Config, KVCompaction),
                            views_compaction = process_config_change(Config, ViewsCompaction)}};
  handle_info(Info, State) ->
      ?log_warning("Got unexpected message ~p:~n~p", [Info, State]),
      {noreply, State}.
  
  terminate(_Reason, _State) ->
      ok.
  
  code_change(_OldVsn, State, _Extra) ->
      {ok, State}.
  
  get_check_interval(Config) ->
      #daemon_config{check_interval=CheckInterval} = compaction_daemon_config(Config),
      CheckInterval.
  
  %% Internal functions
  get_dbs_compactor(BucketName, Config, Force) ->
      OriginalTarget = {[{type, bucket}]},
      [{type, database},
       {important, true},
       {name, BucketName},
       {fa, {fun spawn_dbs_compactor/4,
             [BucketName, Config, Force, OriginalTarget]}}].
  
  -spec spawn_scheduled_kv_compactor(binary(), {#config{}, list()}) -> pid().
  spawn_scheduled_kv_compactor(BucketName, {Config, ConfigProps}) ->
      proc_lib:spawn_link(
        fun () ->
                check_period_and_maybe_exit(Config),
                exit_if_no_bucket(BucketName),
  
                ?log_info("Start compaction of vbuckets for bucket ~s with config: ~n~p",
                          [BucketName, ConfigProps]),
  
                Compactor = get_dbs_compactor(BucketName, Config, false),
                misc:wait_for_process(chain_compactors([Compactor]), infinity)
        end).
  
  get_view_compactors(BucketName, DDocNames, Config, Force) ->
      OriginalTarget = {[{type, bucket}]},
      [ [{type, view},
         {name, <<BucketName/binary, $/, DDocId/binary>>},
         {important, false},
         {fa, {fun spawn_view_compactor/5,
               [BucketName, DDocId, Config, Force =:= true, OriginalTarget]}}] ||
          DDocId <- DDocNames ].
  
  -spec spawn_scheduled_views_compactor(binary(), {#config{}, list()}) -> pid().
  spawn_scheduled_views_compactor(BucketName, {Config, ConfigProps}) ->
      proc_lib:spawn_link(
        fun () ->
                check_period_and_maybe_exit(Config),
                exit_if_no_bucket(BucketName),
  
                try_to_cleanup_indexes(BucketName),
  
                ?log_info("Start compaction of indexes for bucket ~s with config: ~n~p",
                          [BucketName, ConfigProps]),
  
                DDocNames = ddoc_names(BucketName),
                DDocNames =/= [] orelse exit(normal),
  
                Compactors = get_view_compactors(BucketName, DDocNames, Config, false),
                misc:wait_for_process(chain_compactors(Compactors), infinity)
        end).
  
  -spec spawn_forced_bucket_compactor(binary(), {#config{}, list()}) -> pid().
  spawn_forced_bucket_compactor(BucketName, {Config, ConfigProps}) ->
      proc_lib:spawn_link(
        fun () ->
                exit_if_no_bucket(BucketName),
  
                try_to_cleanup_indexes(BucketName),
  
                ?log_info("Start forced compaction of bucket ~s with config: ~n~p",
                          [BucketName, ConfigProps]),
  
                DDocNames = ddoc_names(BucketName),
  
                DbsCompactor = get_dbs_compactor(BucketName, Config, true),
                DDocCompactors = get_view_compactors(BucketName, DDocNames, Config, true),
  
                case Config#config.parallel_view_compact of
                    true ->
  