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 = forall element. Int -> SmallArray element -> Branch element
LeavesBranch Int
hash (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 forall a. Eq a => a -> a -> Bool
== Int
index2
        then do
          Branch a
deeperBranch <- 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 <- forall a. a -> STM (TVar a)
newTVar (forall e. Int -> e -> By6Bits e
By6Bits.singleton Int
index1 Branch a
deeperBranch)
          forall (m :: * -> *) a. Monad m => a -> m a
return (forall element. Hamt element -> Branch element
BranchesBranch (forall element. TVar (By6Bits (Branch element)) -> Hamt element
Hamt TVar (By6Bits (Branch a))
var))
        else forall element. Hamt element -> Branch element
BranchesBranch forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall element. TVar (By6Bits (Branch element)) -> Hamt element
Hamt forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. a -> STM (TVar a)
newTVar (forall e. Int -> e -> Int -> e -> By6Bits e
By6Bits.pair Int
index1 Branch a
branch1 Int
index2 Branch a
branch2)