module PopKey
( type PopKey
, (!)
, PopKey.lookup
, makePopKey
, makePopKey'
, foldrWithKey
, foldlWithKey'
, storage
, storage'
, StoreBlob(..)
, PopKeyEncoding
, PopKeyStore
, PopKeyStore'
, StorePopKey(..)
) where
import qualified Data.ByteString as BS
import Data.Store (encode , decodeEx)
import GHC.Word
import HaskellWorks.Data.FromForeignRegion
import System.IO
import PopKey.Internal2
import PopKey.Internal3
import PopKey.Encoding
{-# INLINE (!) #-}
(!) :: PopKeyEncoding k => PopKey k v -> k -> v
! :: forall k v. PopKeyEncoding k => PopKey k v -> k -> v
(!) (PopKeyInt Bool
_ F s PKPrim
p F' s ByteString -> v
vd) k
k = F' s ByteString -> v
vd do forall s. Int -> F s PKPrim -> F' s ByteString
rawq k
k F s PKPrim
p
(!) (PopKeyAny Bool
_ F s PKPrim
pv F' s ByteString -> v
vd F (Shape k) PKPrim
pk) k
k =
F' s ByteString -> v
vd do forall s. Int -> F s PKPrim -> F' s ByteString
rawq (forall s. F s PKPrim -> F' s ByteString -> Int -> Int -> Int
bin_search2 F (Shape k) PKPrim
pk (forall a. PopKeyEncoding a => a -> F' (Shape a) ByteString
pkEncode k
k) Int
0 (forall s. F s PKPrim -> Int
flength F (Shape k) PKPrim
pk forall a. Num a => a -> a -> a
- Int
1)) F s PKPrim
pv
{-# INLINE lookup #-}
lookup :: PopKeyEncoding k => PopKey k v -> k -> Maybe v
lookup :: forall k v. PopKeyEncoding k => PopKey k v -> k -> Maybe v
lookup s :: PopKey k v
s@(PopKeyInt Bool
_ F s PKPrim
p F' s ByteString -> v
vd) k
i = if k
i forall a. Ord a => a -> a -> Bool
>= k
0 Bool -> Bool -> Bool
&& k
i forall a. Ord a => a -> a -> Bool
< forall (t :: * -> *) a. Foldable t => t a -> Int
length PopKey k v
s
then forall a. a -> Maybe a
Just (F' s ByteString -> v
vd do forall s. Int -> F s PKPrim -> F' s ByteString
rawq k
i F s PKPrim
p)
else forall a. Maybe a
Nothing
lookup (PopKeyAny Bool
_ F s PKPrim
pv F' s ByteString -> v
vd F (Shape k) PKPrim
pk) k
k = do
let i :: Int
i = forall s. F s PKPrim -> F' s ByteString -> Int -> Int -> Int
bin_search2 F (Shape k) PKPrim
pk (forall a. PopKeyEncoding a => a -> F' (Shape a) ByteString
pkEncode k
k) Int
0 (forall s. F s PKPrim -> Int
flength F (Shape k) PKPrim
pk forall a. Num a => a -> a -> a
- Int
1)
if Int
i forall a. Eq a => a -> a -> Bool
== -Int
1
then forall a. Maybe a
Nothing
else forall a. a -> Maybe a
Just (F' s ByteString -> v
vd do forall s. Int -> F s PKPrim -> F' s ByteString
rawq Int
i F s PKPrim
pv)
storage :: (PopKeyEncoding k , PopKeyEncoding v)
=> FilePath -> PopKeyStore k v
storage :: forall k v.
(PopKeyEncoding k, PopKeyEncoding v) =>
FilePath -> PopKeyStore k v
storage FilePath
p =
forall k v.
(forall (f :: * -> *). Foldable f => f (k, v) -> IO ())
-> IO (PopKey k v) -> PopKeyStore k v
PopKeyStore
do \f (k, v)
d -> do
let (ByteString
b1,ByteString
b2) = forall a. BiSerialize a => a -> (ByteString, ByteString)
bencode (forall k v. PopKey k v -> SPopKey k v
toSPopKey (forall (f :: * -> *) k v.
(Foldable f, PopKeyEncoding k, PopKeyEncoding v) =>
f (k, v) -> PopKey k v
makePopKey f (k, v)
d))
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile FilePath
p IOMode
WriteMode \Handle
fh -> do
Handle -> ByteString -> IO ()
BS.hPut Handle
fh (forall a. Store a => a -> ByteString
encode (forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
BS.length ByteString
b1) :: Word64))
Handle -> ByteString -> IO ()
BS.hPut Handle
fh ByteString
b1
Handle -> ByteString -> IO ()
BS.hPut Handle
fh ByteString
b2
do Handle
fh <- FilePath -> IOMode -> IO Handle
openBinaryFile FilePath
p IOMode
ReadMode
Word64
w64 :: Word64 <- forall a. Store a => ByteString -> a
decodeEx forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Handle -> Int -> IO ByteString
BS.hGet Handle
fh Int
8
let s :: Int
s = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w64
ByteString
b1 <- Handle -> Int -> IO ByteString
BS.hGet Handle
fh Int
s
Handle -> IO ()
hClose Handle
fh
ByteString
b2 <- Int -> ByteString -> ByteString
BS.drop (Int
8 forall a. Num a => a -> a -> a
+ Int
s) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromForeignRegion a => FilePath -> IO a
mmapFromForeignRegion FilePath
p
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall k v.
(PopKeyEncoding k, PopKeyEncoding v) =>
SPopKey k v -> PopKey k v
fromSPopKey (forall a. BiSerialize a => (ByteString, ByteString) -> a
bdecode (ByteString
b1,ByteString
b2)))
storage' :: PopKeyEncoding v
=> FilePath -> PopKeyStore' v
storage' :: forall v. PopKeyEncoding v => FilePath -> PopKeyStore' v
storage' FilePath
p = forall v.
(forall (f :: * -> *). Foldable f => f v -> IO ())
-> IO (PopKey Int v) -> PopKeyStore' v
PopKeyStore'
do \f v
d -> do
let (ByteString
b1,ByteString
b2) = forall a. BiSerialize a => a -> (ByteString, ByteString)
bencode (forall k v. PopKey k v -> SPopKey k v
toSPopKey (forall (f :: * -> *) v.
(Foldable f, PopKeyEncoding v) =>
f v -> PopKey Int v
makePopKey' f v
d))
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile FilePath
p IOMode
WriteMode \Handle
fh -> do
Handle -> ByteString -> IO ()
BS.hPut Handle
fh (forall a. Store a => a -> ByteString
encode (forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
BS.length ByteString
b1) :: Word64))
Handle -> ByteString -> IO ()
BS.hPut Handle
fh ByteString
b1
Handle -> ByteString -> IO ()
BS.hPut Handle
fh ByteString
b2
do Handle
fh <- FilePath -> IOMode -> IO Handle
openBinaryFile FilePath
p IOMode
ReadMode
Word64
w64 :: Word64 <- forall a. Store a => ByteString -> a
decodeEx forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Handle -> Int -> IO ByteString
BS.hGet Handle
fh Int
8
let s :: Int
s = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w64
ByteString
b1 <- Handle -> Int -> IO ByteString
BS.hGet Handle
fh Int
s
Handle -> IO ()
hClose Handle
fh
ByteString
b2 <- Int -> ByteString -> ByteString
BS.drop (Int
8 forall a. Num a => a -> a -> a
+ Int
s) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromForeignRegion a => FilePath -> IO a
mmapFromForeignRegion FilePath
p
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall v. PopKeyEncoding v => SPopKey Int v -> PopKey Int v
fromSPopKey' (forall a. BiSerialize a => (ByteString, ByteString) -> a
bdecode (ByteString
b1,ByteString
b2)))