我需要有关数据结构的建议,以用作原子更改日志.
我正在尝试实现以下算法.有一个传入更改流更新内存映射.在类似Haskell的伪代码中
update :: DataSet -> SomeListOf Change -> Change -> STM (DataSet, SomeListOf Change)
update dataSet existingChanges newChange = do
...
return (dataSet, existingChanges ++ [newChange])
Run Code Online (Sandbox Code Playgroud)
其中DataSet是一个映射(目前它是来自stm-containers包的Map,https: //hackage.haskell.org/package/stm-containers-0.2.10/docs/STMContainers-Map.html ).从任意数量的线程调用整个"更新".由于域语义,一些Change可以被拒绝,我使用throwSTM来抛弃事务的影响.如果成功提交,则会将"newChange"添加到列表中.
存在单独的线程,它调用以下函数:
flush :: STM (DataSet, SomeListOf Change) -> IO ()
Run Code Online (Sandbox Code Playgroud)
该函数应该将DataSet的当前快照与更改列表(它必须是一致的对)一起取出并将其刷新到文件系统,即
flush data = do
(dataSet, changes) <- atomically $ readTVar data_
-- write them both to FS
-- ...
atomically $ writeTVar data_ (dataSet, [])
Run Code Online (Sandbox Code Playgroud)
我需要有关用于"SomeListOf Change"的数据结构的建议.我不想使用[更改],因为它"太有序"而且我担心会有太多冲突,这将迫使整个事务重试.如果我错了,请纠正我.
我不能使用Set(https://hackage.haskell.org/package/stm-containers-0.2.10/docs/STMContainers-Set.html),因为我仍然需要保留一些订单,例如事务提交的顺序.我可以用TChan它,它看起来像一个很好的匹配(准确的交易秩序提交),但我不知道如何实现"刷新"功能,使得它会给整个更改日志的统一视图在一起使用DataSet.
当前的实现是https://github.com/lolepezy/rpki-pub-server/blob/add-storage/src/RRDP/Repo.hs,分别在函数applyActionsToState和rrdpSyncThread中.它使用TChan,似乎以错误的方式做到了.
先感谢您.
更新:合理的答案似乎是这样的 …
我有这样的类型级列表
data TList (ixs :: [*]) (f :: * -> *) where
TNil :: TList '[] f
(:-:) :: f ix -> TList ixs f -> TList (ix ': ixs) f
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用现有的TList生成新的TList.这个想法是有一个功能
genTList :: TList ixs f -> t -> TList ixs g
Run Code Online (Sandbox Code Playgroud)
其中't'是一些能够构造'gx'类型值的函数,其中'x'是列表'ixs'中的一种类型.
所以给定
data Foo x
Run Code Online (Sandbox Code Playgroud)
和(某种)
generate :: forall x . Bar x
Run Code Online (Sandbox Code Playgroud)
我可以得到这样的东西
genTList (Foo Int :-: Foo String) generate = Bar :-: Bar
Run Code Online (Sandbox Code Playgroud)
所以基本上对于类型列表中的每个项'x'我想要一个类型'Bar x'并且还使用无参数构造函数构造它的值,因为我知道'Bar x'没有构造函数参数.
我试图实现一些东西(https://gist.github.com/lolepezy/30820595afd9217083c5ca629e350b55),但它不会合理地检查(合理).
那我该怎么办呢?