@@ -617,6 +617,21 @@ genValidUMapNonEmpty = do
617
617
(rdPairs, ptrs, sPools, dReps) <- genValidTuplesNonEmpty
618
618
pure $ unify rdPairs ptrs sPools dReps
619
619
620
+ -- | Either clamp requested size to the range of @[0, actualSize]@ or generate at random
621
+ -- in the same range when requested size is not supplied.
622
+ uniformSubSize ::
623
+ StatefulGen g m =>
624
+ -- | Requested size
625
+ Maybe Int ->
626
+ -- | Actual size
627
+ Int ->
628
+ g ->
629
+ m Int
630
+ uniformSubSize mReqSize actualSize gen =
631
+ case mReqSize of
632
+ Nothing -> uniformRM (0 , actualSize) gen
633
+ Just reqSize -> pure $ max 0 $ min actualSize reqSize
634
+
620
635
uniformSubSet ::
621
636
(StatefulGen g m , Ord k ) =>
622
637
-- | Size of the subset. If supplied will be clamped to @[0, Set.size s]@ interval,
@@ -626,9 +641,7 @@ uniformSubSet ::
626
641
g ->
627
642
m (Set k )
628
643
uniformSubSet mSubSetSize inputSet gen = do
629
- subSetSize <- case mSubSetSize of
630
- Nothing -> uniformRM (0 , Set. size inputSet) gen
631
- Just n -> pure $ max 0 $ min (Set. size inputSet) n
644
+ subSetSize <- uniformSubSize mSubSetSize (Set. size inputSet) gen
632
645
if subSetSize < Set. size inputSet `div` 2
633
646
then
634
647
goAdd inputSet Set. empty subSetSize
@@ -656,7 +669,21 @@ uniformSubMap ::
656
669
Map k v ->
657
670
g ->
658
671
m (Map k v )
659
- uniformSubMap = uniformSubMapElems Map. insert
672
+ uniformSubMap mSubMapSize inputMap gen = do
673
+ subMapSize <- uniformSubSize mSubMapSize (Map. size inputMap) gen
674
+ if subMapSize < Map. size inputMap `div` 2
675
+ then
676
+ -- Constructing a new Map is faster when less then a half of original Map will be used
677
+ uniformSubMapElems Map. insert (Just subMapSize) inputMap gen
678
+ else
679
+ -- Deleting is faster when more items need to be retained in the Map
680
+ goDelete inputMap (Map. size inputMap - subMapSize)
681
+ where
682
+ goDelete ! acc ! i
683
+ | i <= 0 = pure acc
684
+ | otherwise = do
685
+ ix <- uniformRM (0 , Map. size acc - 1 ) gen
686
+ goDelete (Map. deleteAt ix acc) (i - 1 )
660
687
661
688
uniformSubMapElems ::
662
689
(StatefulGen g m , Monoid f ) =>
@@ -668,9 +695,7 @@ uniformSubMapElems ::
668
695
g ->
669
696
m f
670
697
uniformSubMapElems insert mSubMapSize inputMap gen = do
671
- subMapSize <- case mSubMapSize of
672
- Nothing -> uniformRM (0 , Map. size inputMap) gen
673
- Just n -> pure $ max 0 $ min (Map. size inputMap) n
698
+ subMapSize <- uniformSubSize mSubMapSize (Map. size inputMap) gen
674
699
go inputMap mempty subMapSize
675
700
where
676
701
go ! s ! acc ! i
0 commit comments