module StmHamt.Constructors.Branch where

import qualified PrimitiveExtras.By6Bits as By6Bits
import qualified StmHamt.IntOps as IntOps
import StmHamt.Prelude
import StmHamt.Types

singleton :: Int -> a -> Branch a
singleton :: forall a. Int -> a -> Branch a
singleton Int
hash a
a = Int -> SmallArray a -> Branch a
forall element. Int -> SmallArray element -> Branch element
LeavesBranch Int
hash (a -> SmallArray a
forall a. a -> SmallArray a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a)

pair :: Int -> Int -> Branch a -> Int -> Branch a -> STM (Branch a)
pair :: forall a.
Int -> Int -> Branch a -> Int -> Branch a -> STM (Branch a)
pair Int
depth Int
hash1 Branch a
branch1 Int
hash2 Branch a
branch2 =
  {-# SCC "pair" #-}
  let index1 :: Int
index1 = Int -> Int -> Int
IntOps.indexAtDepth Int
depth Int
hash1
      index2 :: Int
index2 = Int -> Int -> Int
IntOps.indexAtDepth Int
depth Int
hash2
   in if Int
index1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
index2
        then do
          Branch a
deeperBranch <- Int -> Int -> Branch a -> Int -> Branch a -> STM (Branch a)
forall a.
Int -> Int -> Branch a -> Int -> Branch a -> STM (Branch a)
pair (Int -> Int
IntOps.nextDepth Int
depth) Int
hash1 Branch a
branch1 Int
hash2 Branch a
branch2
          TVar (By6Bits (Branch a))
var <- By6Bits (Branch a) -> STM (TVar (By6Bits (Branch a)))
forall a. a -> STM (TVar a)
newTVar (Int -> Branch a -> By6Bits (Branch a)
forall e. Int -> e -> By6Bits e
By6Bits.singleton Int
index1 Branch a
deeperBranch)
          Branch a -> STM (Branch a)
forall a. a -> STM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Hamt a -> Branch a
forall element. Hamt element -> Branch element
BranchesBranch (TVar (By6Bits (Branch a)) -> Hamt a
forall element. TVar (By6Bits (Branch element)) -> Hamt element
Hamt TVar (By6Bits (Branch a))
var))
        else Hamt a -> Branch a
forall element. Hamt element -> Branch element
BranchesBranch (Hamt a -> Branch a)
-> (TVar (By6Bits (Branch a)) -> Hamt a)
-> TVar (By6Bits (Branch a))
-> Branch a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. TVar (By6Bits (Branch a)) -> Hamt a
forall element. TVar (By6Bits (Branch element)) -> Hamt element
Hamt (TVar (By6Bits (Branch a)) -> Branch a)
-> STM (TVar (By6Bits (Branch a))) -> STM (Branch a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> By6Bits (Branch a) -> STM (TVar (By6Bits (Branch a)))
forall a. a -> STM (TVar a)
newTVar (Int -> Branch a -> Int -> Branch a -> By6Bits (Branch a)
forall e. Int -> e -> Int -> e -> By6Bits e
By6Bits.pair Int
index1 Branch a
branch1 Int
index2 Branch a
branch2)