Implement a way to disable recompaction

In some cases it is a beneficial to be able to temporary disable
recompaction. This commit introduces a way to do so globally or
individually per database or specific index.

The configuration of the feature is as follows:

[view_compaction.recompaction]
enable = true / false %% to set globaly
<db_name> = enable / disable %% to set per db
<db_name>:<idx_name> = enable / disable %% to set per index
diff --git a/src/couch_index.erl b/src/couch_index.erl
index 25fc62a..85d8cb0 100644
--- a/src/couch_index.erl
+++ b/src/couch_index.erl
@@ -199,9 +199,14 @@
     % For indices that require swapping files, we have to make sure we're
     % up to date with the current index. Otherwise indexes could roll back
     % (perhaps considerably) to previous points in history.
-    case NewSeq >= OldSeq of
-        true -> {reply, ok, commit_compacted(NewIdxState, State)};
-        false -> {reply, recompact, State}
+    case is_recompaction_enabled(NewIdxState, State) of
+        true ->
+            case NewSeq >= OldSeq of
+                true -> {reply, ok, commit_compacted(NewIdxState, State)};
+                false -> {reply, recompact, State}
+            end;
+        false ->
+            {reply, ok, commit_compacted(NewIdxState, State)}
     end.
 
 handle_cast({config_change, NewDelay}, State) ->
@@ -411,3 +416,31 @@
         idx_state=NewIdxState1,
         committed=false
      }.
+
+is_recompaction_enabled(IdxState, #st{mod = Mod}) ->
+    DbName = binary_to_list(Mod:get(db_name, IdxState)),
+    IdxName = binary_to_list(Mod:get(idx_name, IdxState)),
+    IdxKey = DbName ++ ":" ++ IdxName,
+
+    IdxSignature = couch_index_util:hexsig((Mod:get(signature, IdxState))),
+
+    Global = get_value("view_compaction", "enabled_recompaction"),
+    PerSignature = get_value("view_compaction.recompaction", IdxSignature),
+    PerIdx = get_value("view_compaction.recompaction", IdxKey),
+    PerDb = get_value("view_compaction.recompaction", DbName),
+
+    find_most_specific([Global, PerDb, PerIdx, PerSignature], true).
+
+find_most_specific(Settings, Default) ->
+    Reversed = lists:reverse([Default | Settings]),
+    [Value | _] = lists:dropwhile(fun(A) -> A =:= undefined end, Reversed),
+    Value.
+
+get_value(Section, Key) ->
+    case config:get(Section, Key) of
+        "enabled" -> true;
+        "disabled" -> false;
+        "true" -> true;
+        "false" -> false;
+        undefined -> undefined
+    end.