From 167ee99f3388596ce81b47b1e976b5057d5d675e Mon Sep 17 00:00:00 2001
From: hofmockel <dreagonfly@gmx.de>
Date: Thu, 27 Aug 2015 21:45:09 +0200
Subject: [PATCH] Change API of compact_range to be compatible with the change
 of rocksdb.

---
 docs/api/database.rst | 30 ++++++++++++++++++++++++------
 docs/changelog.rst    | 11 ++++++++++-
 rocksdb/_rocksdb.pyx  | 23 ++++++++++++++++-------
 rocksdb/db.pxd        |  5 ++---
 rocksdb/options.pxd   | 12 ++++++++++++
 5 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/docs/api/database.rst b/docs/api/database.rst
index 2477bce..2733b4a 100644
--- a/docs/api/database.rst
+++ b/docs/api/database.rst
@@ -238,7 +238,7 @@ Database object
         ``largest_seqno``
             largest seqno in file
 
-    .. py:method:: compact_range(begin=None, end=None, reduce_level=False, target_level=-1)
+    .. py:method:: compact_range(begin=None, end=None, ** options)
 
         Compact the underlying storage for the key range [begin,end].
         The actual compaction interval might be superset of [begin, end].
@@ -256,7 +256,7 @@ Database object
         Note that after the entire database is compacted, all data are pushed
         down to the last level containing any data. If the total data size
         after compaction is reduced, that level might not be appropriate for
-        hosting all the files. In this case, client could set reduce_level
+        hosting all the files. In this case, client could set change_level
         to ``True``, to move the files back to the minimum level capable of holding
         the data set or a given level (specified by non-negative target_level).
 
@@ -264,11 +264,29 @@ Database object
                             If ``None`` start at the beginning of the database.
         :param bytes end: Key where to end compaction.
                           If ``None`` end at the last key of the database.
-        :param bool reduce_level:  If ``True`` allow rocksdb to move the data to
-                                   another level, if the current is not big enouth.
+        :param bool change_level:  If ``True``, compacted files will be moved to
+                                   the minimum level capable of holding the data
+                                   or given level (specified by non-negative target_level).
                                    If ``False`` you may end with a bigger level
-                                   than configured.
-        :param int target_level: Level where to push the the range to compact.
+                                   than configured. Default is ``False``.
+        :param int target_level: If change_level is true and target_level have non-negative
+                                 value, compacted files will be moved to target_level.
+                                 Default is ``-1``.
+        :param string bottommost_level_compaction:
+            For level based compaction, we can configure if we want to
+            skip/force bottommost level compaction. By default level based
+            compaction will only compact the bottommost level if there is a
+            compaction filter. It can be set to the following values.
+
+            ``skip``
+                Skip bottommost level compaction
+
+            ``if_compaction_filter``
+                Only compact bottommost level if there is a compaction filter.
+                This is the default.
+
+            ``force``
+                Always compact bottommost level
         
     .. py:attribute:: options
 
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 654ad9d..44f8479 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -4,7 +4,16 @@ Changelog
 Version 0.4
 -----------
 
-*  Added :py:func:`repair_db`
+* Added :py:func:`repair_db`.
+
+Backward Incompatible Changes:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Changed API of :py:meth:`rocksdb.DB.compact_range`.
+
+    * Only allow keyword arguments.
+    * Changed ``reduce_level`` to ``change_level``.
+    * Add new argument called ``bottommost_level_compaction``.
 
 
 Version 0.3
diff --git a/rocksdb/_rocksdb.pyx b/rocksdb/_rocksdb.pyx
index 99e841a..2cb8b3a 100644
--- a/rocksdb/_rocksdb.pyx
+++ b/rocksdb/_rocksdb.pyx
@@ -1557,7 +1557,21 @@ cdef class DB(object):
 
         return ret
 
-    def compact_range(self, begin=None, end=None, reduce_level=False, target_level=-1):
+    def compact_range(self, begin=None, end=None, **py_options):
+        cdef options.CompactRangeOptions c_options
+
+        c_options.change_level = py_options.get('change_level', False)
+        c_options.target_level = py_options.get('target_level', -1)
+
+        blc = py_options.get('bottommost_level_compaction', 'if_compaction_filter')
+        if blc == 'skip':
+            c_options.bottommost_level_compaction = options.blc_skip
+        elif blc == 'if_compaction_filter':
+            c_options.bottommost_level_compaction = options.blc_is_filter
+        elif blc == 'force':
+            c_options.bottommost_level_compaction = options.blc_force
+        else:
+            raise ValueError("bottommost_level_compaction is not valid")
 
         cdef Status st
         cdef Slice begin_val
@@ -1577,12 +1591,7 @@ cdef class DB(object):
             end_val = bytes_to_slice(end)
             end_ptr = cython.address(end_val)
 
-
-        st = self.db.CompactRange(
-            begin_ptr,
-            end_ptr,
-            reduce_level,
-            target_level)
+        st = self.db.CompactRange(c_options, begin_ptr, end_ptr)
         check_status(st)
 
     @staticmethod
diff --git a/rocksdb/db.pxd b/rocksdb/db.pxd
index afd444f..a83786b 100644
--- a/rocksdb/db.pxd
+++ b/rocksdb/db.pxd
@@ -106,10 +106,9 @@ cdef extern from "rocksdb/db.h" namespace "rocksdb":
             uint64_t*) nogil except+
 
         Status CompactRange(
+            const options.CompactRangeOptions&,
             const Slice*,
-            const Slice*,
-            cpp_bool,
-            int) nogil except+
+            const Slice*) nogil except+
 
         int NumberLevels() nogil except+
         int MaxMemCompactionLevel() nogil except+
diff --git a/rocksdb/options.pxd b/rocksdb/options.pxd
index de8db40..ea1daaf 100644
--- a/rocksdb/options.pxd
+++ b/rocksdb/options.pxd
@@ -2,6 +2,7 @@ from libcpp cimport bool as cpp_bool
 from libcpp.string cimport string
 from libcpp.vector cimport vector
 from libc.stdint cimport uint64_t
+from libc.stdint cimport uint32_t
 from std_memory cimport shared_ptr
 from comparator cimport Comparator
 from merge_operator cimport MergeOperator
@@ -117,3 +118,14 @@ cdef extern from "rocksdb/options.h" namespace "rocksdb":
 
     cdef cppclass FlushOptions:
         cpp_bool wait
+
+    ctypedef enum BottommostLevelCompaction:
+        blc_skip "rocksdb::BottommostLevelCompaction::kSkip"
+        blc_is_filter "rocksdb::BottommostLevelCompaction::kIfHaveCompactionFilter"
+        blc_force "rocksdb::BottommostLevelCompaction::kForce"
+
+    cdef cppclass CompactRangeOptions:
+        cpp_bool change_level
+        int target_level
+        uint32_t target_path_id
+        BottommostLevelCompaction bottommost_level_compaction
-- 
GitLab