summaryrefslogtreecommitdiff
path: root/src/Erebos/Storage
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2026-06-17 17:08:10 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2026-06-19 21:22:59 +0200
commit962e1ba9ffa0c4c6f038ce1b64925e637a3cbc76 (patch)
tree8272178dc10e384b6837180acaefda1df2b8059e /src/Erebos/Storage
parenta9697ffdf3690c7db68a256c0a0b68941d0937b8 (diff)
Property data type to find updates more efficiently
Diffstat (limited to 'src/Erebos/Storage')
-rw-r--r--src/Erebos/Storage/Graph.hs58
1 files changed, 51 insertions, 7 deletions
diff --git a/src/Erebos/Storage/Graph.hs b/src/Erebos/Storage/Graph.hs
index 815e0f7..97c5543 100644
--- a/src/Erebos/Storage/Graph.hs
+++ b/src/Erebos/Storage/Graph.hs
@@ -13,6 +13,10 @@ module Erebos.Storage.Graph (
storedRoots,
walkAncestors,
+ Property,
+ emptyProperty,
+ propertyValue, propertyValueFirst,
+ findProperty', findPropertyUpdate,
findProperty,
findPropertyFirst,
@@ -186,15 +190,55 @@ walkAncestors f = helper . sortBy cmp
Just GT -> LT
_ -> compare x y
-findProperty :: forall a b. Storable a => (a -> Maybe b) -> [Stored a] -> [b]
-findProperty sel = map (fromJust . sel . fromStored) . filterAncestors . (findPropHeads sel =<<)
-findPropertyFirst :: forall a b. Storable a => (a -> Maybe b) -> [Stored a] -> Maybe b
-findPropertyFirst sel = fmap (fromJust . sel . fromStored) . listToMaybe . filterAncestors . (findPropHeads sel =<<)
+data Property a b = Property
+ { propSelector :: Stored a -> Maybe b
+ , propSource :: [ Stored a ]
+ , propHeads :: StoredTips a
+ }
+
+emptyProperty :: (a -> Maybe b) -> Property a b
+emptyProperty sel = Property
+ { propSelector = sel . fromStored
+ , propSource = []
+ , propHeads = []
+ }
+
+propertyValue :: Property a b -> [ b ]
+propertyValue Property {..} = map (fromJust . propSelector) $ propHeads
-findPropHeads :: forall a b. Storable a => (a -> Maybe b) -> Stored a -> [Stored a]
-findPropHeads sel sobj | Just _ <- sel $ fromStored sobj = [sobj]
- | otherwise = findPropHeads sel =<< previous sobj
+propertyValueFirst :: Property a b -> Maybe b
+propertyValueFirst Property {..} = fmap (fromJust . propSelector) $ listToMaybe $ propHeads
+
+findProperty' :: forall a b. Storable a => (a -> Maybe b) -> [ Stored a ] -> Property a b
+findProperty' sel propSource =
+ let propSelector = sel . fromStored
+ propHeads = filterAncestors $ findPropHeads (isJust . propSelector) =<< propSource
+ in Property {..}
+
+findPropertyUpdate :: forall a b. Storable a => Property a b -> [ Stored a ] -> Property a b
+findPropertyUpdate prop source = prop
+ { propSource = source
+ , propHeads = secondPass
+ }
+ where
+ selectedOrOldSource x = x `elem` propSource prop || isJust (propSelector prop x)
+ firstPass = findPropHeads selectedOrOldSource =<< source
+ ( foundOldSource, foundNewHeads ) = partition (`elem` propSource prop) firstPass
+ secondPass = filterAncestors $ if
+ | sort foundOldSource == propSource prop -> propHeads prop ++ foundNewHeads
+ | otherwise -> (findPropHeads (isJust . propSelector prop) =<< foundOldSource) ++ foundNewHeads
+
+findProperty :: forall a b. Storable a => (a -> Maybe b) -> [ Stored a ] -> [ b ]
+findProperty sel = propertyValue . findProperty' sel
+
+findPropertyFirst :: forall a b. Storable a => (a -> Maybe b) -> [ Stored a ] -> Maybe b
+findPropertyFirst sel = propertyValueFirst . findProperty' sel
+
+findPropHeads :: forall a. Storable a => (Stored a -> Bool) -> Stored a -> [ Stored a ]
+findPropHeads sel sobj
+ | sel sobj = [ sobj ]
+ | otherwise = findPropHeads sel =<< previous sobj
-- | Compute symmetrict difference between two stored histories. In other