packages feed

keyvaluehash 0.3.0.2 → 0.3.1

raw patch · 7 files changed

+119/−7 lines, 7 files

Files

+ cbits/posix.c view
@@ -0,0 +1,21 @@+#include "HsMsync.h"++#define _LARGEFILE64_SOURCE 1+#define _FILE_OFFSET_BITS 64++#include <sys/mman.h>++int system_io_msync(void *ptr, size_t size, int hs_flags)+{+    int flags = 0;+    if (hs_flags & 1) {+        flags |= MS_SYNC;+    }+    if (hs_flags & 2) {+        flags |= MS_ASYNC;+    }+    if (hs_flags & 4) {+        flags |= MS_INVALIDATE;+    }+    return msync(ptr, size, flags);+}
+ cbits/win32.c view
@@ -0,0 +1,7 @@+#include "HsMsync.h"++#include <sys/mman.h>++int system_io_msync(void *ptr, size_t size, int hs_flags)+{+}
keyvaluehash.cabal view
@@ -1,12 +1,22 @@ name:                keyvaluehash-version:             0.3.0.2+version:             0.3.1 synopsis:            Pure Haskell key/value store implementation--- description:         +description:         A simple bytestring key/value store implemented+                     in terms of hash table over a file.++                     It cannot yet grow/shrink the hash table as+                     needed, nor does it free old unused (key,value)+                     pair storage.++                     Mostly useful for applications that need not+                     worry about the size of their persistent store.++                     Reduces dependency hell. license:             BSD3 license-file:        LICENSE author:              Eyal Lotem maintainer:          eyal.lotem@gmail.com--- copyright:           +copyright:           Eyal Lotem category:            Database build-type:          Simple cabal-version:       >=1.8@@ -14,8 +24,17 @@ library   hs-Source-Dirs:      src   exposed-modules:     Database.KeyValueHash-  other-modules:       Database.GrowingFile, Database.FileArray+  other-modules:       Database.GrowingFile, Database.FileArray, System.IO.MMap.Sync   build-depends:       base >= 3 && <10, filepath, directory, bytestring, hashable,                        binary, derive, mmap, array, storable-record+  Include-dirs:        cbits   ghc-options:         -O2 -Wall   ghc-prof-options:    -Wall -auto-all -caf-all -rtsopts+  if os(mingw32)+      C-sources:       cbits/win32.c+  else+      C-sources:       cbits/posix.c++source-repository head+  type: git+  location: https://github.com/Peaker/keyvaluehash.git
src/Database/FileArray.hs view
@@ -4,6 +4,7 @@   , create, open, close   , Element(..)   , unsafeElement -- no index checks+  , msync   ) where  import Control.Monad (when)@@ -17,9 +18,10 @@ import qualified Foreign.Storable as Storable import qualified System.IO as IO import qualified System.IO.MMap as MMap+import qualified System.IO.MMap.Sync as MMapSync  data FileArray a = FileArray-  { _faCount :: Word64+  { faCount :: Word64   , faPtr :: ForeignPtr a   } @@ -69,3 +71,12 @@   withForeignPtr (faPtr fileArray) $ \keysPtr -> do     let ptr = keysPtr `plusPtr` fromIntegral (ix * elementSize fileArray)     return $ Element (Storable.peek ptr) (Storable.poke ptr)++msync :: Storable a => FileArray a -> IO ()+msync fileArray =+  withForeignPtr (faPtr fileArray) $+  \ptr ->+  MMapSync.msync ptr (fromIntegral fileSize)+  (Just MMapSync.Async) MMapSync.NoInvalidate+  where+    fileSize = faCount fileArray * elementSize fileArray
src/Database/GrowingFile.hs view
@@ -4,6 +4,7 @@   , create, open, close   , readRange, writeRange   , append+  , msync   ) where  import Control.Applicative (liftA2)@@ -22,6 +23,7 @@ import qualified Foreign.Storable as Storable import qualified System.IO as IO import qualified System.IO.MMap as MMap+import qualified System.IO.MMap.Sync as MMapSync  data Header = Header   { hAllocated :: Word64@@ -152,3 +154,10 @@   resize gfile header newUsed   writeRange gfile curUsed bs   return curUsed++msync :: GrowingFile -> IO ()+msync gfile = do+  header <- readHeader gfile+  fptr <- readIORef (gfPtr gfile)+  withForeignPtr fptr $ \ptr ->+    MMapSync.msync ptr (fromIntegral (hUsed header)) (Just MMapSync.Async) MMapSync.NoInvalidate
src/Database/KeyValueHash.hs view
@@ -6,6 +6,7 @@   , Database, createDatabase, openDatabase, closeDatabase   , withCreateDatabase, withOpenDatabase   , readKey, writeKey, deleteKey+  , msync   ) where  import Control.Applicative ((<$>), (<*>))@@ -15,7 +16,7 @@ import Data.Binary.Put (runPut) import Data.Derive.Binary(makeBinary) import Data.DeriveTH(derive)-import Data.Hashable (Hashable, hash)+import Data.Hashable (hashWithSalt) import Data.List (intercalate) import Data.Monoid (mconcat) import Data.Typeable (Typeable)@@ -66,7 +67,7 @@   }  stdHash :: HashFunction-stdHash = mkHashFunc "Hashable" (fromIntegral . hash)+stdHash = mkHashFunc "Hashable" (fromIntegral . hashWithSalt 0xDEADBEEF)  type ValuePtr = Word64 -- offset in values file type KeyPtr = Word64 -- index in key file@@ -280,3 +281,8 @@     Nothing ->       -- TODO: Throw exception?       return ()++msync :: Database -> IO ()+msync db = do+  FileArray.msync $ dbKeysArray db+  GrowingFile.msync $ dbValues db
+ src/System/IO/MMap/Sync.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE ForeignFunctionInterface #-}+module System.IO.MMap.Sync (msync, SyncFlag(..), InvalidateFlag(..)) where++import Control.Monad (when)+import Data.Int (Int64)+import Foreign.C.Error (throwErrno)+import Foreign.C.Types (CInt(..), CSize(..))+import Foreign.Ptr (Ptr)++-- TODO: This should be in the mmap package++data SyncFlag = Async | Sync+  deriving (Eq, Ord, Read, Show)+data InvalidateFlag = Invalidate | NoInvalidate+  deriving (Eq, Ord, Read, Show)++foreign import ccall unsafe "HsMsync.h system_io_msync"+    c_system_io_msync :: Ptr a -> CSize -> CInt -> IO CInt++mkMSyncFlag :: Maybe SyncFlag -> CInt+mkMSyncFlag Nothing = 0+mkMSyncFlag (Just Sync) = 1+mkMSyncFlag (Just Async) = 2++mkInvalidateFlag :: InvalidateFlag -> CInt+mkInvalidateFlag NoInvalidate = 0+mkInvalidateFlag Invalidate = 4++mkFlags :: Maybe SyncFlag -> InvalidateFlag -> CInt+mkFlags mSyncFlag invalidateFlag =+  mkMSyncFlag mSyncFlag ++  mkInvalidateFlag invalidateFlag++msync :: Ptr a -> Int64 -> Maybe SyncFlag -> InvalidateFlag -> IO ()+msync ptr size mSyncFlag invalidateFlag = do+  res <-+    c_system_io_msync ptr (fromIntegral size) $+    mkFlags mSyncFlag invalidateFlag+  when (res == -1) $ throwErrno "msync failed"