mirror of https://github.com/voidlizard/hbs2
wip
This commit is contained in:
parent
a1992fbda2
commit
fd19634bd1
|
@ -56,8 +56,8 @@ newtype DataFile a = DataFile a
|
||||||
|
|
||||||
newtype IndexFile a = IndexFile a
|
newtype IndexFile a = IndexFile a
|
||||||
|
|
||||||
newtype StateFile = StateFile FileKey
|
newtype StateFile a = StateFile a
|
||||||
deriving newtype (IsString,Eq,Ord,Pretty)
|
deriving newtype (IsString,Eq,Ord,Pretty)
|
||||||
|
|
||||||
class ToFileName a where
|
class ToFileName a where
|
||||||
toFileName :: a -> FilePath
|
toFileName :: a -> FilePath
|
||||||
|
@ -77,7 +77,7 @@ instance ToFileName (DataFile FilePath) where
|
||||||
instance ToFileName (IndexFile FilePath) where
|
instance ToFileName (IndexFile FilePath) where
|
||||||
toFileName (IndexFile fp) = dropExtension fp `addExtension` ".cq"
|
toFileName (IndexFile fp) = dropExtension fp `addExtension` ".cq"
|
||||||
|
|
||||||
instance ToFileName StateFile where
|
instance ToFileName (StateFile FileKey) where
|
||||||
toFileName (StateFile fk) = toFileName fk
|
toFileName (StateFile fk) = toFileName fk
|
||||||
|
|
||||||
newtype FilePrio = FilePrio (Down TimeSpec)
|
newtype FilePrio = FilePrio (Down TimeSpec)
|
||||||
|
|
|
@ -777,7 +777,7 @@ ncqListDirFossils ncq = do
|
||||||
<&> List.filter (\f -> List.isPrefixOf "fossil-" f && List.isSuffixOf ".data" f)
|
<&> List.filter (\f -> List.isPrefixOf "fossil-" f && List.isSuffixOf ".data" f)
|
||||||
<&> HS.toList . HS.fromList
|
<&> HS.toList . HS.fromList
|
||||||
|
|
||||||
ncqListStateFiles :: forall m . MonadIO m => NCQStorage2 -> m [(TimeSpec, StateFile)]
|
ncqListStateFiles :: forall m . MonadIO m => NCQStorage2 -> m [(TimeSpec, StateFile FileKey)]
|
||||||
ncqListStateFiles ncq = do
|
ncqListStateFiles ncq = do
|
||||||
let wd = ncqGetWorkDir ncq
|
let wd = ncqGetWorkDir ncq
|
||||||
dirFiles wd
|
dirFiles wd
|
||||||
|
@ -818,7 +818,7 @@ ncqRepair me@NCQStorage2{..} = do
|
||||||
|
|
||||||
readState path = ncqReadStateKeys me path <&> fmap DataFile
|
readState path = ncqReadStateKeys me path <&> fmap DataFile
|
||||||
|
|
||||||
tryLoadState (fk :: StateFile) = liftIO do
|
tryLoadState (fk :: StateFile FileKey) = liftIO do
|
||||||
|
|
||||||
debug $ "tryLoadState" <+> pretty fk
|
debug $ "tryLoadState" <+> pretty fk
|
||||||
|
|
||||||
|
@ -978,7 +978,7 @@ ncqStateUpdate me@NCQStorage2{..} ops' = withSem ncqStateSem $ flip runContT pur
|
||||||
d -> pure d
|
d -> pure d
|
||||||
|
|
||||||
|
|
||||||
ncqDumpCurrentState :: MonadUnliftIO m => NCQStorage2 -> m StateFile
|
ncqDumpCurrentState :: MonadUnliftIO m => NCQStorage2 -> m (StateFile FileKey)
|
||||||
ncqDumpCurrentState me@NCQStorage2{..} = do
|
ncqDumpCurrentState me@NCQStorage2{..} = do
|
||||||
files <- ncqListTrackedFiles me
|
files <- ncqListTrackedFiles me
|
||||||
name <- ncqGetNewStateName me
|
name <- ncqGetNewStateName me
|
||||||
|
@ -1263,7 +1263,7 @@ ncqCompactStep me@NCQStorage2{..} = withSem ncqMergeSem $ flip runContT pure $ c
|
||||||
|
|
||||||
readTVarIO r
|
readTVarIO r
|
||||||
|
|
||||||
ncqReadStateKeys :: forall m . MonadUnliftIO m => NCQStorage2 -> StateFile -> m [FileKey]
|
ncqReadStateKeys :: forall m . MonadUnliftIO m => NCQStorage2 -> StateFile FileKey -> m [FileKey]
|
||||||
ncqReadStateKeys me path = liftIO do
|
ncqReadStateKeys me path = liftIO do
|
||||||
keys <- BS8.readFile (ncqGetFileName me (toFileName path))
|
keys <- BS8.readFile (ncqGetFileName me (toFileName path))
|
||||||
<&> filter (not . BS8.null) . BS8.lines
|
<&> filter (not . BS8.null) . BS8.lines
|
||||||
|
|
|
@ -132,7 +132,7 @@ data NCQStorage2 =
|
||||||
, ncqTrackedFiles :: TVar TrackedFiles
|
, ncqTrackedFiles :: TVar TrackedFiles
|
||||||
, ncqStateVersion :: TVar StateVersion
|
, ncqStateVersion :: TVar StateVersion
|
||||||
, ncqStateUsage :: TVar (IntMap (Int, HashSet FileKey))
|
, ncqStateUsage :: TVar (IntMap (Int, HashSet FileKey))
|
||||||
, ncqStateName :: TVar (Maybe StateFile)
|
, ncqStateName :: TVar (Maybe (StateFile FileKey))
|
||||||
, ncqStateSem :: TSem
|
, ncqStateSem :: TSem
|
||||||
, ncqCachedEntries :: TVar Int
|
, ncqCachedEntries :: TVar Int
|
||||||
, ncqWrites :: TVar Int
|
, ncqWrites :: TVar Int
|
||||||
|
|
|
@ -4,6 +4,7 @@ import HBS2.Storage.NCQ3.Internal.Prelude
|
||||||
import HBS2.Storage.NCQ3.Internal.Types
|
import HBS2.Storage.NCQ3.Internal.Types
|
||||||
import HBS2.Storage.NCQ3.Internal.State
|
import HBS2.Storage.NCQ3.Internal.State
|
||||||
|
|
||||||
|
import System.Posix.Files qualified as PFS
|
||||||
import Streaming.Prelude qualified as S
|
import Streaming.Prelude qualified as S
|
||||||
import Network.ByteOrder qualified as N
|
import Network.ByteOrder qualified as N
|
||||||
import Control.Monad.Trans.Cont
|
import Control.Monad.Trans.Cont
|
||||||
|
@ -14,8 +15,9 @@ ncqIndexFile :: MonadUnliftIO m => NCQStorage3 -> DataFile FileKey -> m FilePath
|
||||||
ncqIndexFile n@NCQStorage3{} fk = do
|
ncqIndexFile n@NCQStorage3{} fk = do
|
||||||
|
|
||||||
let fp = toFileName fk & ncqGetFileName n
|
let fp = toFileName fk & ncqGetFileName n
|
||||||
dest <- ncqGetNewFileKey n
|
fki <- ncqGetNewFileKey n IndexFile
|
||||||
<&> ncqGetFileName n . toFileName . IndexFile
|
|
||||||
|
let dest = ncqGetFileName n (toFileName (IndexFile fki))
|
||||||
|
|
||||||
debug $ "INDEX" <+> pretty fp <+> pretty dest
|
debug $ "INDEX" <+> pretty fp <+> pretty dest
|
||||||
|
|
||||||
|
@ -38,7 +40,12 @@ ncqIndexFile n@NCQStorage3{} fk = do
|
||||||
|
|
||||||
mv result dest
|
mv result dest
|
||||||
|
|
||||||
-- ncqStateUpdate n [F 0 (coerce fk)]
|
stat <- liftIO $ PFS.getFileStatus dest
|
||||||
|
let ts = PFS.modificationTimeHiRes stat
|
||||||
|
|
||||||
|
ncqStateUpdate n do
|
||||||
|
ncqStateAddIndexFile ts fki
|
||||||
|
ncqStateAddDataFile (coerce fk)
|
||||||
|
|
||||||
pure dest
|
pure dest
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ module HBS2.Storage.NCQ3.Internal.Prelude
|
||||||
, ToFileName(..)
|
, ToFileName(..)
|
||||||
, IndexFile(..)
|
, IndexFile(..)
|
||||||
, DataFile(..)
|
, DataFile(..)
|
||||||
|
, StateFile(..)
|
||||||
|
, FilePrio(..)
|
||||||
, ByteString
|
, ByteString
|
||||||
, Vector, (!)
|
, Vector, (!)
|
||||||
, Seq(..), (|>),(<|)
|
, Seq(..), (|>),(<|)
|
||||||
|
@ -23,6 +25,8 @@ module HBS2.Storage.NCQ3.Internal.Prelude
|
||||||
, HashMap
|
, HashMap
|
||||||
, HashPSQ
|
, HashPSQ
|
||||||
, IntMap
|
, IntMap
|
||||||
|
, Set
|
||||||
|
, Down(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import HBS2.Prelude as Exported
|
import HBS2.Prelude as Exported
|
||||||
|
@ -46,6 +50,8 @@ import Data.HashSet (HashSet)
|
||||||
import Data.HashMap.Strict (HashMap)
|
import Data.HashMap.Strict (HashMap)
|
||||||
import Data.HashPSQ (HashPSQ)
|
import Data.HashPSQ (HashPSQ)
|
||||||
import Data.IntMap (IntMap)
|
import Data.IntMap (IntMap)
|
||||||
|
import Data.Set (Set)
|
||||||
|
import Data.Ord (Down(..))
|
||||||
|
|
||||||
|
|
||||||
import UnliftIO as Exported
|
import UnliftIO as Exported
|
||||||
|
|
|
@ -152,7 +152,7 @@ ncqStorageRun3 ncq@NCQStorage3{..} = flip runContT pure do
|
||||||
|
|
||||||
openNewDataFile :: forall mx . MonadIO mx => mx (FileKey, Fd)
|
openNewDataFile :: forall mx . MonadIO mx => mx (FileKey, Fd)
|
||||||
openNewDataFile = do
|
openNewDataFile = do
|
||||||
fk <- ncqGetNewFileKey ncq
|
fk <- ncqGetNewFileKey ncq DataFile
|
||||||
let fname = ncqGetFileName ncq (toFileName (DataFile fk))
|
let fname = ncqGetFileName ncq (toFileName (DataFile fk))
|
||||||
touch fname
|
touch fname
|
||||||
let flags = defaultFileFlags { exclusive = False, creat = Just 0o666 }
|
let flags = defaultFileFlags { exclusive = False, creat = Just 0o666 }
|
||||||
|
|
|
@ -3,8 +3,17 @@ module HBS2.Storage.NCQ3.Internal.State where
|
||||||
import HBS2.Storage.NCQ3.Internal.Prelude
|
import HBS2.Storage.NCQ3.Internal.Prelude
|
||||||
import HBS2.Storage.NCQ3.Internal.Types
|
import HBS2.Storage.NCQ3.Internal.Types
|
||||||
|
|
||||||
import Data.ByteString.Char8 qualified as BS8
|
import Data.List qualified as List
|
||||||
import Text.Printf
|
import Control.Monad.Reader
|
||||||
|
import Data.HashSet qualified as HS
|
||||||
|
|
||||||
|
import UnliftIO.IO.File
|
||||||
|
import UnliftIO.IO
|
||||||
|
import System.IO qualified as IO
|
||||||
|
|
||||||
|
newtype StateOP a =
|
||||||
|
StateOP { fromStateOp :: ReaderT NCQStorage3 STM a }
|
||||||
|
deriving newtype (Functor,Applicative,Monad,MonadReader NCQStorage3)
|
||||||
|
|
||||||
ncqGetFileName :: NCQStorage3 -> FilePath -> FilePath
|
ncqGetFileName :: NCQStorage3 -> FilePath -> FilePath
|
||||||
ncqGetFileName ncq fp = ncqGetWorkDir ncq </> takeFileName fp
|
ncqGetFileName ncq fp = ncqGetWorkDir ncq </> takeFileName fp
|
||||||
|
@ -15,12 +24,52 @@ ncqGetWorkDir NCQStorage3{..} = ncqRoot </> show ncqGen
|
||||||
ncqGetLockFileName :: NCQStorage3 -> FilePath
|
ncqGetLockFileName :: NCQStorage3 -> FilePath
|
||||||
ncqGetLockFileName ncq = ncqGetFileName ncq ".lock"
|
ncqGetLockFileName ncq = ncqGetFileName ncq ".lock"
|
||||||
|
|
||||||
ncqGetNewFileKey :: forall m . MonadIO m
|
ncqGetNewFileKey :: forall f m . (ToFileName f, MonadIO m)
|
||||||
=> NCQStorage3
|
=> NCQStorage3
|
||||||
|
-> ( FileKey -> f )
|
||||||
-> m FileKey
|
-> m FileKey
|
||||||
ncqGetNewFileKey me@NCQStorage3{..} = fix \next -> do
|
ncqGetNewFileKey me@NCQStorage3{..} fnameOf = fix \next -> do
|
||||||
n <- atomically $ stateTVar ncqStateFileSeq (\x -> (x, succ x))
|
n <- atomically $ stateTVar ncqStateFileSeq (\x -> (x, succ x))
|
||||||
let fname = ncqMakeFossilName n
|
here <- doesFileExist (ncqGetFileName me (toFileName $ fnameOf n))
|
||||||
here <- doesFileExist (ncqGetFileName me fname)
|
|
||||||
if here then next else pure n
|
if here then next else pure n
|
||||||
|
|
||||||
|
{- HLINT ignore "Eta reduce"-}
|
||||||
|
|
||||||
|
ncqStateUpdate :: MonadIO m
|
||||||
|
=> NCQStorage3
|
||||||
|
-> StateOP a
|
||||||
|
-> m ()
|
||||||
|
ncqStateUpdate ncq@NCQStorage3{..} action = do
|
||||||
|
snkFile <- ncqGetNewFileKey ncq StateFile <&> ncqGetFileName ncq . toFileName . StateFile
|
||||||
|
(n,i,f) <- atomically do
|
||||||
|
runReaderT (fromStateOp action) ncq
|
||||||
|
n <- readTVar ncqStateFileSeq
|
||||||
|
i <- readTVar ncqStateIndex
|
||||||
|
f <- readTVar ncqStateFiles
|
||||||
|
pure (n,i,f)
|
||||||
|
|
||||||
|
liftIO $ withBinaryFileDurableAtomic snkFile WriteMode $ \fh -> do
|
||||||
|
for_ i $ \(Down p, fk) -> do
|
||||||
|
IO.hPrint fh $ "i" <+> pretty fk <+> pretty (round @_ @Word64 p)
|
||||||
|
|
||||||
|
for_ f $ \fk -> do
|
||||||
|
IO.hPrint fh $ "f" <+> pretty fk
|
||||||
|
|
||||||
|
IO.hPrint fh $ "n" <+> pretty n
|
||||||
|
|
||||||
|
ncqStateAddDataFile :: FileKey -> StateOP ()
|
||||||
|
ncqStateAddDataFile fk = do
|
||||||
|
NCQStorage3{..} <- ask
|
||||||
|
StateOP $ lift do
|
||||||
|
modifyTVar ncqStateFiles (HS.insert fk)
|
||||||
|
|
||||||
|
ncqStateAddIndexFile :: POSIXTime
|
||||||
|
-> FileKey
|
||||||
|
-> StateOP ()
|
||||||
|
|
||||||
|
ncqStateAddIndexFile ts fk = do
|
||||||
|
NCQStorage3{..} <- ask
|
||||||
|
StateOP $ lift do
|
||||||
|
modifyTVar' ncqStateIndex $ \xs ->
|
||||||
|
List.sortOn fst ((Down ts, fk) : xs)
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,9 @@ instance ToFileName (DataFile FileKey) where
|
||||||
instance ToFileName (IndexFile FileKey) where
|
instance ToFileName (IndexFile FileKey) where
|
||||||
toFileName (IndexFile fk) = printf "i-%08x.cq" (coerce @_ @Word32 fk)
|
toFileName (IndexFile fk) = printf "i-%08x.cq" (coerce @_ @Word32 fk)
|
||||||
|
|
||||||
|
instance ToFileName (StateFile FileKey) where
|
||||||
|
toFileName (StateFile fk) = printf "s-%08x" (coerce @_ @Word32 fk)
|
||||||
|
|
||||||
data NCQEntry =
|
data NCQEntry =
|
||||||
NCQEntry
|
NCQEntry
|
||||||
{ ncqEntryData :: !ByteString
|
{ ncqEntryData :: !ByteString
|
||||||
|
@ -49,7 +52,7 @@ data NCQStorage3 =
|
||||||
, ncqIdleThrsh :: Double
|
, ncqIdleThrsh :: Double
|
||||||
, ncqMMapCache :: TVar (HashPSQ FileKey CachePrio CachedMMap)
|
, ncqMMapCache :: TVar (HashPSQ FileKey CachePrio CachedMMap)
|
||||||
, ncqStateFiles :: TVar (HashSet FileKey)
|
, ncqStateFiles :: TVar (HashSet FileKey)
|
||||||
, ncqStateIndex :: TVar (HashSet FileKey)
|
, ncqStateIndex :: TVar [(Down POSIXTime, FileKey)] -- backward timestamp order
|
||||||
, ncqStateFileSeq :: TVar FileKey
|
, ncqStateFileSeq :: TVar FileKey
|
||||||
, ncqStateVersion :: TVar StateVersion
|
, ncqStateVersion :: TVar StateVersion
|
||||||
, ncqStateUsage :: TVar (IntMap (Int, HashSet FileKey))
|
, ncqStateUsage :: TVar (IntMap (Int, HashSet FileKey))
|
||||||
|
|
Loading…
Reference in New Issue