module Database.LSMTree.Extras (
showPowersOf10
, showPowersOf
, groupsOfN
, vgroupsOfN
) where
import Data.List (find)
import qualified Data.List as List
import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NE
import Data.Maybe (fromJust)
import qualified Data.Vector as V
import Text.Printf
showPowersOf10 :: Int -> String
showPowersOf10 :: Int -> String
showPowersOf10 = Int -> Int -> String
showPowersOf Int
10
showPowersOf :: Int -> Int -> String
showPowersOf :: Int -> Int -> String
showPowersOf Int
factor Int
n
| Int
factor Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
1 = String -> String
forall a. HasCallStack => String -> a
error String
"showPowersOf: factor must be larger than 1"
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = String
"n < 0"
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = String
"n == 0"
| Bool
otherwise = String -> Int -> Int -> String
forall r. PrintfType r => String -> r
printf String
"%d <= n < %d" Int
lb Int
ub
where
ub :: Int
ub = Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust ((Int -> Bool) -> [Int] -> Maybe Int
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (Int
n <) ((Int -> Int) -> Int -> [Int]
forall a. (a -> a) -> a -> [a]
iterate (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
factor) Int
factor))
lb :: Int
lb = Int
ub Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
factor
groupsOfN :: Int -> [a] -> [NonEmpty a]
groupsOfN :: forall a. Int -> [a] -> [NonEmpty a]
groupsOfN Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = String -> [a] -> [NonEmpty a]
forall a. HasCallStack => String -> a
error String
"groupsOfN: n <= 0"
| Bool
otherwise = ([a] -> Maybe (NonEmpty a, [a])) -> [a] -> [NonEmpty a]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
List.unfoldr [a] -> Maybe (NonEmpty a, [a])
f
where f :: [a] -> Maybe (NonEmpty a, [a])
f [a]
xs = let ([a]
ys, [a]
zs) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
List.splitAt Int
n [a]
xs
in (,[a]
zs) (NonEmpty a -> (NonEmpty a, [a]))
-> Maybe (NonEmpty a) -> Maybe (NonEmpty a, [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a] -> Maybe (NonEmpty a)
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [a]
ys
vgroupsOfN :: Int -> V.Vector a -> V.Vector (V.Vector a)
vgroupsOfN :: forall a. Int -> Vector a -> Vector (Vector a)
vgroupsOfN Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = String -> Vector a -> Vector (Vector a)
forall a. HasCallStack => String -> a
error String
"groupsOfN: n <= 0"
| Bool
otherwise = (Vector a -> Maybe (Vector a, Vector a))
-> Vector a -> Vector (Vector a)
forall b a. (b -> Maybe (a, b)) -> b -> Vector a
V.unfoldr Vector a -> Maybe (Vector a, Vector a)
f
where
f :: Vector a -> Maybe (Vector a, Vector a)
f Vector a
xs
| Vector a -> Bool
forall a. Vector a -> Bool
V.null Vector a
xs
= Maybe (Vector a, Vector a)
forall a. Maybe a
Nothing
| Bool
otherwise
= (Vector a, Vector a) -> Maybe (Vector a, Vector a)
forall a. a -> Maybe a
Just ((Vector a, Vector a) -> Maybe (Vector a, Vector a))
-> (Vector a, Vector a) -> Maybe (Vector a, Vector a)
forall a b. (a -> b) -> a -> b
$ Int -> Vector a -> (Vector a, Vector a)
forall a. Int -> Vector a -> (Vector a, Vector a)
V.splitAt Int
n Vector a
xs