@@ -14,7 +14,6 @@ module PlutusCore.Value (
1414 toFlatList ,
1515 totalSize ,
1616 maxInnerSize ,
17- maxKeyLength ,
1817 insertCoin ,
1918 deleteCoin ,
2019 lookupCoin ,
@@ -29,7 +28,6 @@ import Control.DeepSeq (NFData)
2928import Data.Bifunctor
3029import Data.Bitraversable
3130import Data.ByteString (ByteString )
32- import Data.ByteString qualified as B
3331import Data.ByteString.Base64 qualified as Base64
3432import Data.Functor
3533import Data.Hashable (Hashable )
@@ -62,10 +60,6 @@ data Value
6260
6361 Invariant: all values are positive.
6462 -}
65- !(IntMap Int )
66- {- ^ Map from length to the number of `ByteString`s of that length
67- (across both outer and inner maps).
68- -}
6963 {- # UNPACK #-} !Int
7064 {-^ Total size, i.e., sum total of inner map sizes. This avoids recomputing
7165 the total size during the costing of operations like `unionValue`.
@@ -78,7 +72,7 @@ data Value
7872The map is guaranteed to not contain empty inner map or zero amount.
7973-}
8074unpack :: Value -> NestedMap
81- unpack (Value v _ _ _ ) = v
75+ unpack (Value v _ _) = v
8276{-# INLINE unpack #-}
8377
8478{-| Pack a map from (currency symbol, token name) to amount into a `Value`.
@@ -91,19 +85,11 @@ pack = pack' . normalize
9185
9286-- | Like `pack` but does not normalize.
9387pack' :: NestedMap -> Value
94- pack' v = Value v sizes lens size
88+ pack' v = Value v sizes size
9589 where
96- (sizes, lens, size) = Map. foldrWithKey' alg (mempty , mempty , 0 ) v
97- alg currency inner (ss, ls, s) =
98- ( incCount (Map. size inner) ss
99- , IntMap. unionWith
100- (+)
101- (incCount (B. length currency) ls)
102- ( Map. foldrWithKey'
103- (\ token _ -> incCount (B. length token))
104- mempty
105- inner
106- )
90+ (sizes, size) = Map. foldl' alg (mempty , 0 ) v
91+ alg (ss, s) inner =
92+ ( IntMap. alter (maybe (Just 1 ) (Just . (+ 1 ))) (Map. size inner) ss
10793 , s + Map. size inner
10894 )
10995{-# INLINEABLE pack' #-}
@@ -112,20 +98,16 @@ pack' v = Value v sizes lens size
11298contained in the `Value`.
11399-}
114100totalSize :: Value -> Int
115- totalSize (Value _ _ _ size) = size
101+ totalSize (Value _ _ size) = size
116102{-# INLINE totalSize #-}
117103
118104-- | Size of the largest inner map.
119105maxInnerSize :: Value -> Int
120- maxInnerSize (Value _ sizes _ _ ) = maybe 0 fst (IntMap. lookupMax sizes)
106+ maxInnerSize (Value _ sizes _) = maybe 0 fst (IntMap. lookupMax sizes)
121107{-# INLINE maxInnerSize #-}
122108
123- -- | Maximum `ByteString` length, across both outer and inner maps.
124- maxKeyLength :: Value -> Int
125- maxKeyLength (Value _ _ lens _) = maybe 0 fst (IntMap. lookupMax lens)
126-
127109empty :: Value
128- empty = Value mempty mempty mempty 0
110+ empty = Value mempty mempty 0
129111{-# INLINE empty #-}
130112
131113toList :: Value -> [(ByteString , [(ByteString , Integer )])]
@@ -155,60 +137,47 @@ instance Pretty Value where
155137the size of the largest inner map.
156138-}
157139insertCoin :: ByteString -> ByteString -> Integer -> Value -> Value
158- insertCoin currency token amt v@ (Value outer sizes lens size)
140+ insertCoin currency token amt v@ (Value outer sizes size)
159141 | amt == 0 = deleteCoin currency token v
160142 | otherwise =
161- let (r, outer') = Map. alterF f currency outer
162- (sizes', lens', size') = case r of
163- Just (old, currencyInserted) ->
164- ( updateSizes old (old + 1 ) sizes
165- , (if currencyInserted then incCount (B. length currency) else id )
166- (incCount (B. length token) lens)
167- , size + 1
168- )
169- Nothing -> (sizes, lens, size)
170- in Value outer' sizes' lens' size'
143+ let (mold, outer') = Map. alterF f currency outer
144+ (sizes', size') = case mold of
145+ Just old -> (updateSizes old (old + 1 ) sizes, size + 1 )
146+ Nothing -> (sizes, size)
147+ in Value outer' sizes' size'
171148 where
172149 f
173150 :: Maybe (Map ByteString Integer )
174- -> ( -- Just (old size of inner map, whether it is a new currency)
175- -- if the total size grows by 1, otherwise Nothing
176- Maybe (Int , Bool )
151+ -> ( -- Just (old size of inner map) if the total size grows by 1, otherwise Nothing
152+ Maybe Int
177153 , Maybe (Map ByteString Integer )
178154 )
179155 f = \ case
180- Nothing -> (Just ( 0 , True ) , Just (Map. singleton token amt))
156+ Nothing -> (Just 0 , Just (Map. singleton token amt))
181157 Just inner ->
182158 let (isJust -> exists, inner') = Map. insertLookupWithKey (\ _ _ _ -> amt) token amt inner
183- in (if exists then Nothing else Just (Map. size inner, False ), Just inner')
159+ in (if exists then Nothing else Just (Map. size inner), Just inner')
184160{-# INLINEABLE insertCoin #-}
185161
186162-- | \(O(\log \max(m, k))\)
187163deleteCoin :: ByteString -> ByteString -> Value -> Value
188- deleteCoin currency token (Value outer sizes lens size) = Value outer' sizes' lens ' size'
164+ deleteCoin currency token (Value outer sizes size) = Value outer' sizes' size'
189165 where
190- (r, outer') = Map. alterF f currency outer
191- (sizes', lens', size') = case r of
192- Just (old, currencyDeleted) ->
193- ( updateSizes old (old - 1 ) sizes
194- , (if currencyDeleted then decLen (B. length currency) else id ) (decLen (B. length token) lens)
195- , size - 1
196- )
197- Nothing -> (sizes, lens, size)
166+ (mold, outer') = Map. alterF f currency outer
167+ (sizes', size') = case mold of
168+ Just old -> (updateSizes old (old - 1 ) sizes, size - 1 )
169+ Nothing -> (sizes, size)
198170 f
199171 :: Maybe (Map ByteString Integer )
200- -> ( -- Just (old size of inner map, whether a currency is deleted)
201- -- if the total size shrinks by 1, otherwise Nothing
202- Maybe (Int , Bool )
172+ -> ( -- Just (old size of inner map) if the total size shrinks by 1, otherwise Nothing
173+ Maybe Int
203174 , Maybe (Map ByteString Integer )
204175 )
205176 f = \ case
206177 Nothing -> (Nothing , Nothing )
207178 Just inner ->
208179 let (amt, inner') = Map. updateLookupWithKey (\ _ _ -> Nothing ) token inner
209- in ( amt $> (Map. size inner, Map. null inner')
210- , if Map. null inner' then Nothing else Just inner'
211- )
180+ in (amt $> Map. size inner, if Map. null inner' then Nothing else Just inner')
212181
213182-- | \(O(\log \max(m, k))\)
214183lookupCoin :: ByteString -> ByteString -> Value -> Integer
@@ -238,8 +207,9 @@ valueContains v = Map.foldrWithKey' go True . unpack
238207 )
239208
240209{-| The precise complexity is complicated, but an upper bound
241- is \(O(n_{1} \log n_{2}) + O(n_{2})\), where \(n_{1}\) is the total size of the smaller
242- value, and \(n_{2}\) is the total size of the bigger value.
210+ is \(O(n_{1} \log n_{2}) + O(m)\), where \(n_{1}\) is the total size of the smaller
211+ value, \(n_{2}\) is the total size of the bigger value, and \(m\) is the
212+ combined size of the outer maps.
243213-}
244214unionValue :: Value -> Value -> Value
245215unionValue (unpack -> vA) (unpack -> vB) =
@@ -308,18 +278,9 @@ updateSizes old new = dec . inc
308278 inc =
309279 if new == 0
310280 then id
311- else incCount new
281+ else IntMap. alter ( maybe ( Just 1 ) ( Just . ( + 1 ))) new
312282 dec =
313283 if old == 0
314284 then id
315285 else IntMap. update (\ n -> if n <= 1 then Nothing else Just (n - 1 )) old
316286{-# INLINEABLE updateSizes #-}
317-
318- -- | Increment the count at the given key.
319- incCount :: Int -> IntMap Int -> IntMap Int
320- incCount = IntMap. alter (maybe (Just 1 ) (Just . (+ 1 )))
321- {-# INLINEABLE incCount #-}
322-
323- decLen :: Int -> IntMap Int -> IntMap Int
324- decLen = IntMap. update (\ n -> if n <= 1 then Nothing else Just (n - 1 ))
325- {-# INLINEABLE decLen #-}
0 commit comments