packages feed

rocksdb-haskell-jprupp 2.4.0 → 2.5.0

raw patch · 6 files changed

+120/−16 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Database.RocksDB: BlockCacheUsage :: Property
+ Database.RocksDB: CurSizeAllMemTables :: Property
+ Database.RocksDB: EstimateTableReadersMem :: Property
+ Database.RocksDB: PropertyName :: String -> Property
+ Database.RocksDB: [createMissingColumnFamilies] :: Config -> !Bool
+ Database.RocksDB: [maxTotalWalSize] :: Config -> !Maybe Int
+ Database.RocksDB: getPropertyCF :: DB -> ColumnFamily -> Property -> IO (Maybe ByteString)
- Database.RocksDB: Config :: !Bool -> !Bool -> !Bool -> !Maybe Int -> !Maybe Int -> !Bool -> !Maybe Int -> !Maybe Int -> Config
+ Database.RocksDB: Config :: !Bool -> !Bool -> !Bool -> !Bool -> !Maybe Int -> !Maybe Int -> !Bool -> !Maybe Int -> !Maybe Int -> !Maybe Int -> Config

Files

CHANGELOG.md view
@@ -1,3 +1,17 @@+## 2.5.0++ * Add the `EstimateTableReadersMem`, `CurSizeAllMemTables` and+   `BlockCacheUsage` properties, and `PropertyName` for any other property by+   its name.+ * Add `getPropertyCF` to read a property of a column family.+ * Add `maxTotalWalSize` (`max_total_wal_size`) to `Config`, to bound the+   write-ahead log.+ * Add `createMissingColumnFamilies` (`create_missing_column_families`) to+   `Config`, to add column families to an existing database.+ * Destroy the handle of the default column family when `withDBCF` opens an+   existing database. It was leaked, and RocksDB built with assertions+   aborted when the database was closed.+ ## 2.4.0   * Add `writeBufferSize` (`write_buffer_size`) and `dbWriteBufferSize`
rocksdb-haskell-jprupp.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           rocksdb-haskell-jprupp-version:        2.4.0+version:        2.5.0 synopsis:       Haskell bindings for RocksDB description:    See README at <https://github.com/jprupp/rocksdb-haskell#readme> category:       Database, FFI
src/Database/RocksDB/Base.hs view
@@ -39,7 +39,7 @@     , releaseSnapshot      -- * Administrative Functions-    , Property (..), getProperty+    , Property (..), getProperty, getPropertyCF     , destroy     , repair     , approximateSize@@ -67,7 +67,19 @@ import           System.Directory  -- | Properties exposed by RocksDB-data Property = NumFilesAtLevel Int | Stats | SSTables+data Property+    = NumFilesAtLevel Int+    | Stats+    | SSTables+    -- | @rocksdb.estimate-table-readers-mem@: memory for index and filter+    -- blocks of open table files, outside the block cache+    | EstimateTableReadersMem+    -- | @rocksdb.cur-size-all-mem-tables@: memory of all memtables+    | CurSizeAllMemTables+    -- | @rocksdb.block-cache-usage@: memory used by the block cache+    | BlockCacheUsage+    -- | any other property, by its full name+    | PropertyName String     deriving (Eq, Show)  data BatchOp = Put !ByteString !ByteString@@ -165,9 +177,15 @@                         cf_names_array                         cf_opts_array                         cf_ptrs_array-                    cfs <- peekArray (length cf_cfgs + 1) cf_ptrs_array+                    (deflt, cfs) <- peekArray (length cf_cfgs + 1) cf_ptrs_array >>= \case+                        d : cs -> return (d, cs)+                        [] -> error "rocksdb_open_column_families returned no handles"+                    -- Every handle must be destroyed before the database is+                    -- closed. The default column family is not kept, so+                    -- release its handle now; the database keeps its own.+                    c_rocksdb_column_family_handle_destroy deflt                     return DB { rocksDB = db_ptr-                              , columnFamilies = tail cfs+                              , columnFamilies = cfs                               , readOpts = read_opts                               , writeOpts = write_opts                               }@@ -197,17 +215,33 @@ -- | Get a DB property. getProperty :: DB -> Property -> IO (Maybe ByteString) getProperty DB{rocksDB = db_ptr} p =-    withCString (prop p) $-    c_rocksdb_property_value db_ptr >=> \case-    val_ptr | val_ptr == nullPtr -> return Nothing-            | otherwise -> do-                  res <- Just <$> BS.packCString val_ptr-                  freeCString val_ptr-                  return res-  where-    prop (NumFilesAtLevel i) = "rocksdb.num-files-at-level" ++ show i-    prop Stats               = "rocksdb.stats"-    prop SSTables            = "rocksdb.sstables"+    withCString (propertyName p) $ \name ->+    c_rocksdb_property_value db_ptr name >>= propertyResult++-- | Get a property of a column family. Many properties, such as the memory+-- of memtables and table readers, are kept per column family.+getPropertyCF :: DB -> ColumnFamily -> Property -> IO (Maybe ByteString)+getPropertyCF DB{rocksDB = db_ptr} cf p =+    withCString (propertyName p) $ \name ->+    c_rocksdb_property_value_cf db_ptr cf name >>= propertyResult++propertyResult :: CString -> IO (Maybe ByteString)+propertyResult val_ptr+    | val_ptr == nullPtr = return Nothing+    | otherwise = do+          res <- BS.packCString val_ptr+          freeCString val_ptr+          return (Just res)++propertyName :: Property -> String+propertyName = \case+    NumFilesAtLevel i       -> "rocksdb.num-files-at-level" ++ show i+    Stats                   -> "rocksdb.stats"+    SSTables                -> "rocksdb.sstables"+    EstimateTableReadersMem -> "rocksdb.estimate-table-readers-mem"+    CurSizeAllMemTables     -> "rocksdb.cur-size-all-mem-tables"+    BlockCacheUsage         -> "rocksdb.block-cache-usage"+    PropertyName n          -> n  -- | Destroy the given RocksDB database. destroy :: FilePath -> Options -> IO ()
src/Database/RocksDB/C.hs view
@@ -44,6 +44,7 @@     , c_rocksdb_create_snapshot     , c_rocksdb_release_snapshot     , c_rocksdb_property_value+    , c_rocksdb_property_value_cf     , c_rocksdb_approximate_sizes     , c_rocksdb_destroy_db     , c_rocksdb_repair_db@@ -74,6 +75,8 @@     , c_rocksdb_options_set_max_open_files     , c_rocksdb_options_set_write_buffer_size     , c_rocksdb_options_set_db_write_buffer_size+    , c_rocksdb_options_set_max_total_wal_size+    , c_rocksdb_options_set_create_missing_column_families     , c_rocksdb_options_set_prefix_extractor     , c_rocksdb_options_set_block_based_table_factory     , c_rocksdb_block_based_options_create@@ -249,6 +252,9 @@ foreign import ccall safe "rocksdb/c.h rocksdb_property_value"   c_rocksdb_property_value :: RocksDB -> CString -> IO CString +foreign import ccall safe "rocksdb/c.h rocksdb_property_value_cf"+  c_rocksdb_property_value_cf :: RocksDB -> ColumnFamily -> CString -> IO CString+ foreign import ccall safe "rocksdb/c.h rocksdb_approximate_sizes"   c_rocksdb_approximate_sizes :: RocksDB                               -> CInt@@ -378,6 +384,12 @@  foreign import ccall safe "rocksdb/c.h rocksdb_options_set_db_write_buffer_size"   c_rocksdb_options_set_db_write_buffer_size :: Options -> CSize -> IO ()++foreign import ccall safe "rocksdb/c.h rocksdb_options_set_max_total_wal_size"+  c_rocksdb_options_set_max_total_wal_size :: Options -> Word64 -> IO ()++foreign import ccall safe "rocksdb/c.h rocksdb_options_set_create_missing_column_families"+  c_rocksdb_options_set_create_missing_column_families :: Options -> CBool -> IO ()  foreign import ccall safe "rocksdb/c.h rocksdb_options_set_prefix_extractor"   c_rocksdb_options_set_prefix_extractor :: Options
src/Database/RocksDB/Internal.hs view
@@ -48,6 +48,9 @@ data Config = Config { createIfMissing :: !Bool                      , errorIfExists   :: !Bool                      , paranoidChecks  :: !Bool+                     , createMissingColumnFamilies :: !Bool+                       -- ^ create the column families passed to 'withDBCF'+                       -- that an existing database does not have yet                      , maxFiles        :: !(Maybe Int)                      , prefixLength    :: !(Maybe Int)                      , bloomFilter     :: !Bool@@ -58,17 +61,25 @@                        -- ^ bytes for all memtables across all column                        -- families (RocksDB default unlimited); database-wide,                        -- ignored in column family configs+                     , maxTotalWalSize :: !(Maybe Int)+                       -- ^ bytes of write-ahead log after which the column+                       -- families holding the oldest log are flushed, so it+                       -- can be deleted (RocksDB default: four times the+                       -- memtables); database-wide, ignored in column family+                       -- configs                      } deriving (Eq, Show)  instance Default Config where     def = Config { createIfMissing  = False                  , errorIfExists    = False                  , paranoidChecks   = False+                 , createMissingColumnFamilies = False                  , maxFiles         = Nothing                  , prefixLength     = Nothing                  , bloomFilter      = False                  , writeBufferSize  = Nothing                  , dbWriteBufferSize = Nothing+                 , maxTotalWalSize  = Nothing                  }  withOptions :: Config -> (Options -> IO a) -> IO a@@ -87,12 +98,16 @@         c_rocksdb_options_set_write_buffer_size opts . intToCSize     forM_ dbWriteBufferSize $         c_rocksdb_options_set_db_write_buffer_size opts . intToCSize+    forM_ maxTotalWalSize $+        c_rocksdb_options_set_max_total_wal_size opts . fromIntegral     c_rocksdb_options_set_create_if_missing         opts (boolToCBool createIfMissing)     c_rocksdb_options_set_error_if_exists         opts (boolToCBool errorIfExists)     c_rocksdb_options_set_paranoid_checks         opts (boolToCBool paranoidChecks)+    c_rocksdb_options_set_create_missing_column_families+        opts (boolToCBool createMissingColumnFamilies)     f opts   where     with_opts =
test/Spec.hs view
@@ -250,3 +250,32 @@             getCF db two (key 20000) `shouldReturn` Just value             files <- getProperty db SSTables             files `shouldSatisfy` maybe False (not . C.null)+    describe "Properties" $ do+      it "reports memory use, per database and per column family" $ \db -> do+        let one = head (columnFamilies db)+            isNumber = maybe False (\v -> not (C.null v) && C.all (`elem` ['0' .. '9']) v)+        forM_ [1 .. 1000 :: Int] $ \i -> putCF db one (C.pack (show i)) "value"+        mem <- getPropertyCF db one CurSizeAllMemTables+        mem `shouldSatisfy` isNumber+        mem `shouldSatisfy` maybe False ((> 0) . read . C.unpack)+        getProperty db EstimateTableReadersMem >>= (`shouldSatisfy` isNumber)+        getProperty db BlockCacheUsage >>= (`shouldSatisfy` isNumber)+        getProperty db (PropertyName "rocksdb.num-immutable-mem-table")+          >>= (`shouldSatisfy` isNumber)+        getProperty db (PropertyName "rocksdb.no-such-property")+          `shouldReturn` Nothing+      it "opens with a bound on the write-ahead log" $ \_ ->+        withSystemTempDirectory "rocksdb-tests-wal" $ \path ->+          withDBCF path conf {maxTotalWalSize = Just (1024 * 1024)} [("one", conf)] $ \db -> do+            put db "key" "value"+            get db "key" `shouldReturn` Just "value"+    describe "Column families" $ do+      it "adds a column family to an existing database" $ \_ ->+        withSystemTempDirectory "rocksdb-tests-newcf" $ \path -> do+          let open = conf {errorIfExists = False}+          withDBCF path open [("one", open)] $ \db -> put db "key" "value"+          withDBCF path open {createMissingColumnFamilies = True} [("one", open), ("two", open)] $ \db -> do+            get db "key" `shouldReturn` Just "value"+            let two = columnFamilies db !! 1+            putCF db two "new" "cf"+            getCF db two "new" `shouldReturn` Just "cf"