mirror of https://github.com/voidlizard/hbs2
wip
This commit is contained in:
parent
6c5ebfe38e
commit
39764326fa
|
@ -44,7 +44,7 @@ newtype EntrySize = EntrySize Word64
|
||||||
deriving stock Generic
|
deriving stock Generic
|
||||||
|
|
||||||
|
|
||||||
newtype EntryNum = EntryNum Word64
|
newtype EntryNum = EntryNum Word32
|
||||||
deriving newtype (Ord,Eq,Num,Enum,Real,Integral,Show)
|
deriving newtype (Ord,Eq,Num,Enum,Real,Integral,Show)
|
||||||
deriving stock Generic
|
deriving stock Generic
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ data Header =
|
||||||
, hdrVersion :: Word16
|
, hdrVersion :: Word16
|
||||||
, hdrIndexOffset :: EntryOffset
|
, hdrIndexOffset :: EntryOffset
|
||||||
, hdrIndexEntries :: EntryNum
|
, hdrIndexEntries :: EntryNum
|
||||||
|
, hdrGen :: Word32
|
||||||
, hdrPrev :: EntryOffset
|
, hdrPrev :: EntryOffset
|
||||||
}
|
}
|
||||||
deriving stock (Show,Generic)
|
deriving stock (Show,Generic)
|
||||||
|
@ -78,6 +79,7 @@ data CompactStorage =
|
||||||
CompactStorage
|
CompactStorage
|
||||||
{ csHandle :: MVar Handle
|
{ csHandle :: MVar Handle
|
||||||
, csHeaderOff :: IORef EntryOffset
|
, csHeaderOff :: IORef EntryOffset
|
||||||
|
, csHeaderGen :: IORef Word32
|
||||||
, csSeq :: IORef Integer
|
, csSeq :: IORef Integer
|
||||||
, csKeys :: IORef (HashMap ByteString (Either (IndexEntry,Integer) (ByteString,Integer)))
|
, csKeys :: IORef (HashMap ByteString (Either (IndexEntry,Integer) (ByteString,Integer)))
|
||||||
}
|
}
|
||||||
|
@ -106,27 +108,39 @@ compactStorageOpen _ fp = do
|
||||||
|
|
||||||
hoff0 <- newIORef 0
|
hoff0 <- newIORef 0
|
||||||
keys0 <- newIORef mempty
|
keys0 <- newIORef mempty
|
||||||
ss <- newIORef 0
|
ss <- newIORef 0
|
||||||
|
gen0 <- newIORef 0
|
||||||
|
|
||||||
if sz == 0 then
|
if sz == 0 then
|
||||||
pure $ CompactStorage mha hoff0 ss keys0
|
pure $ CompactStorage mha hoff0 gen0 ss keys0
|
||||||
else do
|
else do
|
||||||
(p,header) <- readHeader mha Nothing >>= maybe (throwIO InvalidHeader) pure
|
(p,header) <- readHeader mha Nothing >>= maybe (throwIO InvalidHeader) pure
|
||||||
traceM (show ("HEADER",header))
|
traceM (show ("HEADER",header))
|
||||||
hoff <- newIORef p
|
hoff <- newIORef p
|
||||||
let sto = CompactStorage mha hoff ss keys0
|
let sto = CompactStorage mha hoff gen0 ss keys0
|
||||||
|
updateHeaderGen sto header
|
||||||
readIndex sto (hdrIndexOffset header) (hdrIndexEntries header)
|
readIndex sto (hdrIndexOffset header) (hdrIndexEntries header)
|
||||||
|
|
||||||
flip fix (hdrPrev header) $ \next -> \case
|
flip fix (hdrPrev header) $ \next -> \case
|
||||||
0 -> pure ()
|
0 -> pure ()
|
||||||
off -> do
|
off -> do
|
||||||
(_,pHeader) <- readHeader mha (Just off) >>= maybe (throwIO InvalidHeader) pure
|
(_,pHeader) <- readHeader mha (Just off) >>= maybe (throwIO InvalidHeader) pure
|
||||||
|
updateHeaderGen sto pHeader
|
||||||
traceM (show ("PHEADER",pHeader))
|
traceM (show ("PHEADER",pHeader))
|
||||||
readIndex sto (hdrIndexOffset pHeader) (hdrIndexEntries pHeader)
|
readIndex sto (hdrIndexOffset pHeader) (hdrIndexEntries pHeader)
|
||||||
next (hdrPrev pHeader)
|
next (hdrPrev pHeader)
|
||||||
|
|
||||||
pure sto
|
pure sto
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
updateHeaderGen :: ForCompactStorage m
|
||||||
|
=> CompactStorage
|
||||||
|
-> Header
|
||||||
|
-> m ()
|
||||||
|
updateHeaderGen sto hdr = do
|
||||||
|
writeIORef (csHeaderGen sto) (hdrGen hdr)
|
||||||
|
|
||||||
readIndex :: ForCompactStorage m
|
readIndex :: ForCompactStorage m
|
||||||
=> CompactStorage
|
=> CompactStorage
|
||||||
-> EntryOffset
|
-> EntryOffset
|
||||||
|
@ -196,8 +210,9 @@ compactStorageCommit sto = liftIO do
|
||||||
|
|
||||||
offPrev <- readIORef (csHeaderOff sto)
|
offPrev <- readIORef (csHeaderOff sto)
|
||||||
|
|
||||||
|
pver <- atomicModifyIORef' (csHeaderGen sto) (\v -> (v+1, v))
|
||||||
-- FIXME: maybe-slow-length-calc
|
-- FIXME: maybe-slow-length-calc
|
||||||
appendHeader ha (Just offPrev) offIdx0 (fromIntegral $ length idxEntries)
|
appendHeader ha (Just offPrev) pver offIdx0 (fromIntegral $ length idxEntries)
|
||||||
hFlush ha
|
hFlush ha
|
||||||
|
|
||||||
hSeek ha SeekFromEnd 0
|
hSeek ha SeekFromEnd 0
|
||||||
|
@ -245,16 +260,18 @@ compactStorageClose sto = do
|
||||||
appendHeader :: ForCompactStorage m
|
appendHeader :: ForCompactStorage m
|
||||||
=> Handle
|
=> Handle
|
||||||
-> Maybe EntryOffset -- prev. header
|
-> Maybe EntryOffset -- prev. header
|
||||||
|
-> Word32 -- prev. header version
|
||||||
-> EntryOffset
|
-> EntryOffset
|
||||||
-> EntryNum
|
-> EntryNum
|
||||||
-> m ()
|
-> m ()
|
||||||
appendHeader ha hoffset offset num = do
|
appendHeader ha poffset v ioffset num = do
|
||||||
let bs = word16BE headerMagic
|
let bs = word16BE headerMagic
|
||||||
<> word16BE headerVersion
|
<> word16BE headerVersion
|
||||||
<> word64BE (coerce offset)
|
<> word64BE (coerce ioffset)
|
||||||
<> word64BE (coerce num)
|
<> word32BE (coerce num)
|
||||||
<> word64BE (coerce (fromMaybe 0 hoffset))
|
<> word32BE v
|
||||||
<> byteString (BS.replicate 4 0)
|
<> word64BE (coerce $ fromMaybe 0 poffset)
|
||||||
|
<> word32BE 0 -- reserved
|
||||||
liftIO $ LBS.hPut ha (B.toLazyByteString bs)
|
liftIO $ LBS.hPut ha (B.toLazyByteString bs)
|
||||||
|
|
||||||
readHeader :: ForCompactStorage m
|
readHeader :: ForCompactStorage m
|
||||||
|
@ -279,13 +296,14 @@ readHeader mha moff = do
|
||||||
<*> getWord16be
|
<*> getWord16be
|
||||||
<*> getOffset
|
<*> getOffset
|
||||||
<*> getNum
|
<*> getNum
|
||||||
|
<*> getWord32be
|
||||||
<*> getOffset
|
<*> getOffset
|
||||||
|
|
||||||
pure $ either (const Nothing) (fmap (off,) . Just . view _3) what
|
pure $ either (const Nothing) (fmap (off,) . Just . view _3) what
|
||||||
|
|
||||||
where
|
where
|
||||||
getOffset = EntryOffset <$> getWord64be
|
getOffset = EntryOffset <$> getWord64be
|
||||||
getNum = EntryNum <$> getWord64be
|
getNum = EntryNum <$> getWord32be
|
||||||
|
|
||||||
headerMagic :: Word16
|
headerMagic :: Word16
|
||||||
headerMagic = 32264
|
headerMagic = 32264
|
||||||
|
|
Loading…
Reference in New Issue