Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
A mutable splay tree-based map.
Invariants
Splay tree is a self-adjusting tree that follows the splaying operation heuristic.
http://www.cs.cmu.edu/~sleator/papers/self-adjusting.pdf
Invariants
Left children have keys smaller keys than the parent. Right children have bigger keys than the parent.
Thanks
Synopsis
- type SplayIndex = Int
- undefSI :: SplayIndex
- nullSI :: SplayIndex -> Bool
- data SplayNode k v = SplayNode {
- lSN :: !SplayIndex
- rSN :: !SplayIndex
- keySN :: !k
- valSN :: !v
- type SplayNodeRepr k v = (SplayIndex, SplayIndex, k, v)
- data SplayMap k v s = SplayMap {
- capacitySM :: !Int
- rootSM :: !(MVector s SplayIndex)
- dataSM :: !(Buffer s (SplayNode k v))
- newSM :: (Unbox k, Unbox v, PrimMonad m) => Int -> m (SplayMap k v (PrimState m))
- buildSM :: (Ord k, Unbox k, Unbox v, PrimMonad m) => Int -> Vector (k, v) -> m (SplayMap k v (PrimState m))
- clearSM :: PrimMonad m => SplayMap k v (PrimState m) -> m ()
- lengthSM :: PrimMonad m => SplayMap k v (PrimState m) -> m Int
- lookupSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (k, v))
- insertSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> v -> m (Maybe v)
- insertSM_ :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> v -> m ()
- deleteSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (SplayNode k v))
- deleteSM_ :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m ()
- memberSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m Bool
- _readLMostSM :: (HasCallStack, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex
- _readRMostSM :: (HasCallStack, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex
- _lookupWithSM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> (k -> Ordering) -> Bool -> m (Maybe (k, v))
- lookupLESM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (k, v))
- lookupLTSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (k, v))
- lookupGESM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (k, v))
- lookupGTSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (k, v))
- dfsSM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> m (Vector (k, v))
- rotateRSM :: (HasCallStack, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex
- rotateLSM :: (HasCallStack, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex
- splayBySM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> (k -> Ordering) -> SplayIndex -> m (SplayIndex, Ordering)
- splayLMostSM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex
- splayRMostSM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex
- pushRootSM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> SplayNode k v -> m ()
- popRootSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> m (SplayNode k v)
- writeLSM :: (HasCallStack, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> SplayIndex -> m ()
- writeRSM :: (HasCallStack, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> SplayIndex -> m ()
- writeKSM :: (HasCallStack, Unbox k, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> k -> m ()
- writeVSM :: (HasCallStack, Unbox v, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> v -> m ()
- readLSM :: (HasCallStack, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> m SplayIndex
- readRSM :: (HasCallStack, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> m SplayIndex
- readKSM :: (HasCallStack, Unbox k, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> m k
- readVSM :: (HasCallStack, Unbox v, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> m v
Documentation
type SplayIndex = Int #
undefSI :: SplayIndex #
nullSI :: SplayIndex -> Bool #
Splay tree node.
SplayNode | |
|
Instances
type SplayNodeRepr k v = (SplayIndex, SplayIndex, k, v) #
Internal representation of `SplayNode a` for implementing Unbox
.
Mutable, splay tree-based map.
SplayMap | |
|
newSM :: (Unbox k, Unbox v, PrimMonad m) => Int -> m (SplayMap k v (PrimState m)) #
\(O(N)\) Creates a new SplayMap
of capacity n
.
buildSM :: (Ord k, Unbox k, Unbox v, PrimMonad m) => Int -> Vector (k, v) -> m (SplayMap k v (PrimState m)) #
\(O(N)\) Creates a new SplayMap
of capacity n
with initial values xs
.
TODO: faster implementation?
clearSM :: PrimMonad m => SplayMap k v (PrimState m) -> m () #
\(O(1)\) Resets the splay tree to the initial state.
lookupSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (k, v)) #
Amortized \(O(\log N)\).
insertSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> v -> m (Maybe v) #
Amortized \(O(\log N)\). Returns old value with the same key if there is.
TODO: consider making a multiset with splay tree?
insertSM_ :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> v -> m () #
deleteSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (SplayNode k v)) #
Amortized \(O(\log N)\).
deleteSM_ :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m () #
memberSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m Bool #
_readLMostSM :: (HasCallStack, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex #
Reads the left most child without splaying.
_readRMostSM :: (HasCallStack, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex #
Reads the right most child without splaying.
_lookupWithSM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> (k -> Ordering) -> Bool -> m (Maybe (k, v)) #
Amortized \(O(\log N)\). Internal use only.
lookupLESM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (k, v)) #
Amortized \(O(\log N)\).
lookupLTSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (k, v)) #
Amortized \(O(\log N)\).
lookupGESM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (k, v)) #
Amortized \(O(\log N)\).
lookupGTSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> k -> m (Maybe (k, v)) #
Amortized \(O(\log N)\).
dfsSM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> m (Vector (k, v)) #
Returns (key, value)
pairs sorted by the keys in ascending order.
Splay
rotateRSM :: (HasCallStack, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex #
\(O(1)\) Left child rotation.
Visualization
Move up l
, move i
to the right node of l
, set lr
as the left node of i
.
i* l * .. the side of the child is updated l* r --> ll i ll lr lr r
Returns l
.
rotateLSM :: (HasCallStack, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex #
\(O(1)\) Right child rotation.
Visualization
Move up r
, move i
to the left node of r
, set rl
as the right node of i
.
i* r * .. the side of the child is updated l r* --> i rr rl rr l rl
Returns r
.
splayBySM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> (k -> Ordering) -> SplayIndex -> m (SplayIndex, Ordering) #
Amortized \(O(\log N)\) Splay v
so that it is under r
(or to the root if s is null).
Top-down splaying
The are two known approaches for the splaying operation: bottom-up and top-down. The former is easier to understand but less efficient. The latter is faster and uses less memory.
See also: http://www.cs.cmu.edu/~sleator/papers/self-adjusting.pdf#16
splayLMostSM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex #
splayRMostSM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> SplayIndex -> m SplayIndex #
pushRootSM :: (HasCallStack, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> SplayNode k v -> m () #
Amortized \(O(\log N)\).
popRootSM :: (HasCallStack, Ord k, Unbox k, Unbox v, PrimMonad m) => SplayMap k v (PrimState m) -> m (SplayNode k v) #
Amortized \(O(\log N)\). Removes the current root.
TODO: Less splaying
Internal update
writeLSM :: (HasCallStack, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> SplayIndex -> m () #
Efficiently modify SplayNode
.
writeRSM :: (HasCallStack, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> SplayIndex -> m () #
Efficiently modify SplayNode
.
writeKSM :: (HasCallStack, Unbox k, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> k -> m () #
Efficiently modify SplayNode
.
writeVSM :: (HasCallStack, Unbox v, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> v -> m () #
Efficiently modify SplayNode
.
readLSM :: (HasCallStack, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> m SplayIndex #
Efficiently read SplayNode
.
readRSM :: (HasCallStack, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> m SplayIndex #
Efficiently read SplayNode
.
readKSM :: (HasCallStack, Unbox k, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> m k #
Efficiently read SplayNode
.
readVSM :: (HasCallStack, Unbox v, PrimMonad m) => Buffer (PrimState m) (SplayNode k v) -> SplayIndex -> m v #
Efficiently read SplayNode
.