packages feed

diskhash 0.0.3.2 → 0.0.4.0

raw patch · 6 files changed

+87/−7 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.DiskHash: htLoadRO :: forall a. (Storable a) => FilePath -> Int -> IO (DiskHashRO a)

Files

ChangeLog view
@@ -1,3 +1,6 @@+Version 0.0.4.0 2017-11-27 by luispedro+	* Load hash table into memory+ Version 0.0.3.2 2017-11-09 by luispedro 	* Fix Haskell distribution 
diskhash.cabal view
@@ -1,5 +1,5 @@ name:               diskhash-version:            0.0.3.2+version:            0.0.4.0 synopsis:           Disk-based hash table description:        Disk-based hash table category:           Data
haskell/Data/DiskHash.hs view
@@ -19,6 +19,7 @@     ( DiskHashRO     , DiskHashRW     , htOpenRO+    , htLoadRO     , htOpenRW     , withDiskHashRW     , htLookupRO@@ -33,6 +34,7 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as B8 import Control.Exception (throwIO)+import Control.Monad (when) import System.IO.Unsafe (unsafeDupablePerformIO) import Foreign.Ptr (Ptr, FunPtr, castPtr, nullPtr) import Foreign.ForeignPtr (ForeignPtr, newForeignPtr, withForeignPtr, finalizeForeignPtr)@@ -54,6 +56,7 @@ foreign import ccall "dht_reserve" c_dht_reserve :: Ptr () -> CInt -> Ptr CString -> IO () foreign import ccall "dht_insert" c_dht_insert :: Ptr () -> CString -> Ptr () -> Ptr CString -> IO CInt foreign import ccall "dht_size" c_dht_size :: Ptr () -> IO CSize+foreign import ccall "dht_load_to_memory" c_dht_load_to_memory :: Ptr () -> Ptr CString -> IO CInt foreign import ccall "&dht_free" c_dht_free_p :: FunPtr (Ptr () -> IO ())  -- | Internal function to handle error message interface@@ -76,7 +79,7 @@                                         -> Int                                         -- ^ maximum key size                                         -> IO (DiskHashRW a)-htOpenRW fpath maxk = DiskHashRW <$> open' (undefined :: a) fpath maxk 66+htOpenRW fpath maxk = DiskHashRW <$> open' (undefined :: a) fpath maxk 66 False  -- | open a hash table in read-only mode --@@ -88,10 +91,24 @@                                         -> Int                                         -- ^ maximum key size                                         -> IO (DiskHashRO a)-htOpenRO fpath maxk = DiskHashRO <$> open' (undefined :: a) fpath maxk 0+htOpenRO fpath maxk = DiskHashRO <$> open' (undefined :: a) fpath maxk 0 False -open' :: forall a. (Storable a) => a -> FilePath -> Int -> CInt -> IO HashTable_t-open' unused fpath maxk flags = B.useAsCString (B8.pack fpath) $ \fpath' ->+-- | open a hash table in read-only mode and load it into memory+--+-- The 'maxk' argument can be 0, in which case the value of the maximum key+-- will be taken from the disk file. If not zero, then it is checked against+-- the value on disk and an exception is raised if there is  a mismatch.+--+-- @since 0.0.4.0+htLoadRO :: forall a. (Storable a) => FilePath+                                        -- ^ file path+                                        -> Int+                                        -- ^ maximum key size+                                        -> IO (DiskHashRO a)+htLoadRO fpath maxk = DiskHashRO <$> open' (undefined :: a) fpath maxk 0 True++open' :: forall a. (Storable a) => a -> FilePath -> Int -> CInt -> Bool -> IO HashTable_t+open' unused fpath maxk flags load = B.useAsCString (B8.pack fpath) $ \fpath' ->     alloca $ \err -> do         poke err nullPtr         ht <- c_dht_open2 fpath' (fromIntegral maxk) (fromIntegral $ sizeOf unused) flags err@@ -99,7 +116,12 @@             then do                 errmsg <- getError err                 throwIO $ userError ("Could not open hash table: " ++ show errmsg)-            else+            else do+                when load $ do+                    e <- c_dht_load_to_memory ht err+                    when (e == 2) $ do+                        errmsg <- getError err+                        throwIO $ userError ("Could not load hash table into memory: " ++ show errmsg)                 newForeignPtr c_dht_free_p ht  -- | Open a hash table in read-write mode and pass it to an action
haskell/Data/DiskHash/Tests.hs view
@@ -59,6 +59,17 @@     assertEqual "Lookup" (Just (9 :: Int64)) (htLookupRO "key" ht)     removeFileIfExists outname +case_open_close_load = do+    withDiskHashRW outname 15 $ \ht -> do+        s <- htSizeRW ht+        assertEqual "new table has size 0" s 0+        inserted <- htInsert "key" (9 :: Int64) ht+        assertBool "inserted should have return True" inserted+    ht <- htLoadRO outname 15+    assertEqual "read-only table after reopen (load)" (htSizeRO ht) 1+    assertEqual "Lookup" (Just (9 :: Int64)) (htLookupRO "key" ht)+    removeFileIfExists outname+ -- prop_insert_find :: [(String, Int64)] -> IO Bool prop_insert_find args = ioProperty $ do     let args' = normArgs args
src/diskhash.c view
@@ -19,6 +19,7 @@ enum {     HT_FLAG_CAN_WRITE = 1,     HT_FLAG_HASH_2 = 2,+    HT_FLAG_IS_LOADED = 4, };  typedef struct HashTableHeader {@@ -240,8 +241,39 @@     return rp; } -void dht_free(HashTable* ht) {+int dht_load_to_memory(HashTable* ht, char** err) {+    if (ht->flags_ & HT_FLAG_CAN_WRITE) {+        if (err) *err = "Cannot call dht_load_to_memory on a read/write Diskhash";+        return 1;+    }+    if (ht->flags_ & HT_FLAG_IS_LOADED) {+        if (err) *err = "dht_load_to_memory had already been called.";+        return 1;+    }     munmap(ht->data_, ht->datasize_);+    ht->data_ = malloc(ht->datasize_);+    if (ht->data_) {+        size_t n = read(ht->fd_, ht->data_, ht->datasize_);+        if (n == ht->datasize_) return 0;+        else if (err) *err = "dht_load_to_memory: could not read data from file";+    } else {+        if (err) *err = "dht_load_to_memory: could not allocate memory.";+    }+    free(ht->data_);+    fsync(ht->fd_);+    close(ht->fd_);+    free((char*)ht->fname_);+    free(ht);+    return 2;++}++void dht_free(HashTable* ht) {+    if (ht->flags_ & HT_FLAG_IS_LOADED) {+        free(ht->data_);+    } else {+        munmap(ht->data_, ht->datasize_);+    }     fsync(ht->fd_);     close(ht->fd_);     free((char*)ht->fname_);
src/diskhash.h view
@@ -73,6 +73,18 @@  */ HashTable* dht_open(const char* fpath, HashTableOpts opts, int flags, char**); +/** Load table into memory+ *+ * Return:+ *   0 : success+ *+ *   1 : impossible operation: nothing has been done. Attempting to load a+ *   previously loaded table or a read/write table is impossible.+ *+ *   2 : error: the HashTable has been freed and must not be used.+ */+int dht_load_to_memory(HashTable*, char**);+ /** Lookup a value by key  *  * If the hash table was opened in read-write mode, then the memory returned