-- |
-- Module      : Foundation.Array.Chunked.Unboxed
-- License     : BSD-style -- Maintainer  : Alfredo Di Napoli <alfredo.dinapoli@gmail.com>
-- Stability   : experimental
-- Portability : portable
--
-- Simple array-of-arrays abstraction
--
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}
module Foundation.Array.Chunked.Unboxed
    ( ChunkedUArray
    ) where

import           Data.Typeable
import           Control.Arrow ((***))
import           Basement.BoxedArray (Array)
import qualified Basement.BoxedArray as A
import           Basement.Exception
import           Basement.UArray (UArray)
import qualified Basement.UArray as U
import           Basement.Compat.Bifunctor
import           Basement.Compat.Semigroup
import           Basement.Compat.Base
import           Basement.Types.OffsetSize
import           Basement.PrimType
import           GHC.ST

import           Foundation.Numerical
import           Foundation.Primitive
import qualified Foundation.Collection as C


newtype ChunkedUArray ty = ChunkedUArray (Array (UArray ty))
                      deriving (Int -> ChunkedUArray ty -> ShowS
forall ty.
(PrimType ty, Show ty) =>
Int -> ChunkedUArray ty -> ShowS
forall ty. (PrimType ty, Show ty) => [ChunkedUArray ty] -> ShowS
forall ty. (PrimType ty, Show ty) => ChunkedUArray ty -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ChunkedUArray ty] -> ShowS
$cshowList :: forall ty. (PrimType ty, Show ty) => [ChunkedUArray ty] -> ShowS
show :: ChunkedUArray ty -> String
$cshow :: forall ty. (PrimType ty, Show ty) => ChunkedUArray ty -> String
showsPrec :: Int -> ChunkedUArray ty -> ShowS
$cshowsPrec :: forall ty.
(PrimType ty, Show ty) =>
Int -> ChunkedUArray ty -> ShowS
Show, ChunkedUArray ty -> ChunkedUArray ty -> Bool
ChunkedUArray ty -> ChunkedUArray ty -> Ordering
ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {ty}. (PrimType ty, Ord ty) => Eq (ChunkedUArray ty)
forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Ordering
forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
min :: ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
$cmin :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
max :: ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
$cmax :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
>= :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
$c>= :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
> :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
$c> :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
<= :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
$c<= :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
< :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
$c< :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
compare :: ChunkedUArray ty -> ChunkedUArray ty -> Ordering
$ccompare :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Ordering
Ord, Typeable)

instance PrimType ty => Eq (ChunkedUArray ty) where
  == :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
(==) = forall ty.
PrimType ty =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
equal
instance NormalForm (ChunkedUArray ty) where
    toNormalForm :: ChunkedUArray ty -> ()
toNormalForm (ChunkedUArray Array (UArray ty)
spine) = forall a. NormalForm a => a -> ()
toNormalForm Array (UArray ty)
spine

instance Semigroup (ChunkedUArray a) where
    <> :: ChunkedUArray a -> ChunkedUArray a -> ChunkedUArray a
(<>) = forall a. ChunkedUArray a -> ChunkedUArray a -> ChunkedUArray a
append
instance Monoid (ChunkedUArray a) where
    mempty :: ChunkedUArray a
mempty  = forall a. ChunkedUArray a
empty
    mconcat :: [ChunkedUArray a] -> ChunkedUArray a
mconcat = forall a. [ChunkedUArray a] -> ChunkedUArray a
concat

type instance C.Element (ChunkedUArray ty) = ty

instance PrimType ty => IsList (ChunkedUArray ty) where
    type Item (ChunkedUArray ty) = ty
    fromList :: [Item (ChunkedUArray ty)] -> ChunkedUArray ty
fromList = forall ty. PrimType ty => [ty] -> ChunkedUArray ty
vFromList
    toList :: ChunkedUArray ty -> [Item (ChunkedUArray ty)]
toList = forall ty. PrimType ty => ChunkedUArray ty -> [ty]
vToList

instance PrimType ty => C.Foldable (ChunkedUArray ty) where
    foldl' :: forall a.
(a -> Element (ChunkedUArray ty) -> a)
-> a -> ChunkedUArray ty -> a
foldl' = forall ty a.
PrimType ty =>
(a -> ty -> a) -> a -> ChunkedUArray ty -> a
foldl'
    foldr :: forall a.
(Element (ChunkedUArray ty) -> a -> a)
-> a -> ChunkedUArray ty -> a
foldr = forall ty a.
PrimType ty =>
(ty -> a -> a) -> a -> ChunkedUArray ty -> a
foldr
    -- Use the default foldr' instance

instance PrimType ty => C.Collection (ChunkedUArray ty) where
    null :: ChunkedUArray ty -> Bool
null = forall ty. PrimType ty => ChunkedUArray ty -> Bool
null
    length :: ChunkedUArray ty -> CountOf (Element (ChunkedUArray ty))
length = forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length
    elem :: forall a.
(Eq a, a ~ Element (ChunkedUArray ty)) =>
Element (ChunkedUArray ty) -> ChunkedUArray ty -> Bool
elem   = forall ty. PrimType ty => ty -> ChunkedUArray ty -> Bool
elem
    minimum :: forall a.
(Ord a, a ~ Element (ChunkedUArray ty)) =>
NonEmpty (ChunkedUArray ty) -> Element (ChunkedUArray ty)
minimum = forall ty.
(Ord ty, PrimType ty) =>
NonEmpty (ChunkedUArray ty) -> ty
minimum
    maximum :: forall a.
(Ord a, a ~ Element (ChunkedUArray ty)) =>
NonEmpty (ChunkedUArray ty) -> Element (ChunkedUArray ty)
maximum = forall ty.
(Ord ty, PrimType ty) =>
NonEmpty (ChunkedUArray ty) -> ty
maximum
    all :: (Element (ChunkedUArray ty) -> Bool) -> ChunkedUArray ty -> Bool
all Element (ChunkedUArray ty) -> Bool
p (ChunkedUArray Array (UArray ty)
cua) = forall ty. (ty -> Bool) -> Array ty -> Bool
A.all (forall ty. PrimType ty => (ty -> Bool) -> UArray ty -> Bool
U.all Element (ChunkedUArray ty) -> Bool
p) Array (UArray ty)
cua
    any :: (Element (ChunkedUArray ty) -> Bool) -> ChunkedUArray ty -> Bool
any Element (ChunkedUArray ty) -> Bool
p (ChunkedUArray Array (UArray ty)
cua) = forall ty. (ty -> Bool) -> Array ty -> Bool
A.any (forall ty. PrimType ty => (ty -> Bool) -> UArray ty -> Bool
U.any Element (ChunkedUArray ty) -> Bool
p) Array (UArray ty)
cua

instance PrimType ty => C.Sequential (ChunkedUArray ty) where
    take :: CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
take = forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
take
    drop :: CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
drop = forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop
    splitAt :: CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitAt = forall ty.
PrimType ty =>
CountOf ty
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitAt
    revTake :: CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
revTake = forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revTake
    revDrop :: CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
revDrop = forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revDrop
    splitOn :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> [ChunkedUArray ty]
splitOn = forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> [ChunkedUArray ty]
splitOn
    break :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
break = forall ty.
PrimType ty =>
(ty -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
break
    breakEnd :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
breakEnd = forall ty.
PrimType ty =>
(ty -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
breakEnd
    intersperse :: Element (ChunkedUArray ty) -> ChunkedUArray ty -> ChunkedUArray ty
intersperse = forall ty.
PrimType ty =>
ty -> ChunkedUArray ty -> ChunkedUArray ty
intersperse
    filter :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> ChunkedUArray ty
filter = forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> ChunkedUArray ty
filter
    reverse :: ChunkedUArray ty -> ChunkedUArray ty
reverse = forall ty. PrimType ty => ChunkedUArray ty -> ChunkedUArray ty
reverse
    unsnoc :: ChunkedUArray ty
-> Maybe (ChunkedUArray ty, Element (ChunkedUArray ty))
unsnoc = forall ty.
PrimType ty =>
ChunkedUArray ty -> Maybe (ChunkedUArray ty, ty)
unsnoc
    uncons :: ChunkedUArray ty
-> Maybe (Element (ChunkedUArray ty), ChunkedUArray ty)
uncons = forall ty.
PrimType ty =>
ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty)
uncons
    snoc :: ChunkedUArray ty -> Element (ChunkedUArray ty) -> ChunkedUArray ty
snoc = forall ty.
PrimType ty =>
ChunkedUArray ty -> ty -> ChunkedUArray ty
snoc
    cons :: Element (ChunkedUArray ty) -> ChunkedUArray ty -> ChunkedUArray ty
cons = forall ty.
PrimType ty =>
ty -> ChunkedUArray ty -> ChunkedUArray ty
cons
    find :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> Maybe (Element (ChunkedUArray ty))
find = forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> Maybe ty
find
    sortBy :: (Element (ChunkedUArray ty)
 -> Element (ChunkedUArray ty) -> Ordering)
-> ChunkedUArray ty -> ChunkedUArray ty
sortBy = forall ty.
PrimType ty =>
(ty -> ty -> Ordering) -> ChunkedUArray ty -> ChunkedUArray ty
sortBy
    singleton :: Element (ChunkedUArray ty) -> ChunkedUArray ty
singleton = forall l. IsList l => [Item l] -> l
fromList forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (forall a. a -> [a] -> [a]
:[])
    replicate :: CountOf (Element (ChunkedUArray ty))
-> Element (ChunkedUArray ty) -> ChunkedUArray ty
replicate CountOf (Element (ChunkedUArray ty))
n = forall l. IsList l => [Item l] -> l
fromList forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall c. Sequential c => CountOf (Element c) -> Element c -> c
C.replicate CountOf (Element (ChunkedUArray ty))
n

instance PrimType ty => C.IndexedCollection (ChunkedUArray ty) where
    ! :: ChunkedUArray ty
-> Offset (Element (ChunkedUArray ty))
-> Maybe (Element (ChunkedUArray ty))
(!) ChunkedUArray ty
l Offset (Element (ChunkedUArray ty))
n
        | forall ty. Offset ty -> CountOf ty -> Bool
isOutOfBound Offset (Element (ChunkedUArray ty))
n (forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
l) = forall a. Maybe a
Nothing
        | Bool
otherwise                     = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
index ChunkedUArray ty
l Offset (Element (ChunkedUArray ty))
n
    findIndex :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> Maybe (Offset (Element (ChunkedUArray ty)))
findIndex Element (ChunkedUArray ty) -> Bool
predicate ChunkedUArray ty
c = Offset ty -> Maybe (Offset ty)
loop Offset ty
0
      where
        !len :: CountOf ty
len = forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
c
        loop :: Offset ty -> Maybe (Offset ty)
loop Offset ty
i
            | Offset ty
i forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
len = forall a. Maybe a
Nothing
            | Bool
otherwise  =
                if Element (ChunkedUArray ty) -> Bool
predicate (forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex ChunkedUArray ty
c Offset ty
i) then forall a. a -> Maybe a
Just Offset ty
i else forall a. Maybe a
Nothing

empty :: ChunkedUArray ty
empty :: forall a. ChunkedUArray a
empty = forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray forall a. Array a
A.empty

append :: ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
append :: forall a. ChunkedUArray a -> ChunkedUArray a -> ChunkedUArray a
append (ChunkedUArray Array (UArray ty)
a1) (ChunkedUArray Array (UArray ty)
a2) = forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (forall a. Monoid a => a -> a -> a
mappend Array (UArray ty)
a1 Array (UArray ty)
a2)

concat :: [ChunkedUArray ty] -> ChunkedUArray ty
concat :: forall a. [ChunkedUArray a] -> ChunkedUArray a
concat [ChunkedUArray ty]
x = forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(ChunkedUArray Array (UArray ty)
spine) -> Array (UArray ty)
spine) [ChunkedUArray ty]
x)

vFromList :: PrimType ty => [ty] -> ChunkedUArray ty
vFromList :: forall ty. PrimType ty => [ty] -> ChunkedUArray ty
vFromList [ty]
l = forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray forall a b. (a -> b) -> a -> b
$ forall ty. ty -> Array ty
A.singleton forall a b. (a -> b) -> a -> b
$ forall l. IsList l => [Item l] -> l
fromList [ty]
l

vToList :: PrimType ty => ChunkedUArray ty -> [ty]
vToList :: forall ty. PrimType ty => ChunkedUArray ty -> [ty]
vToList (ChunkedUArray Array (UArray ty)
a) = forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ forall l. IsList l => l -> [Item l]
toList forall a b. (a -> b) -> a -> b
$ forall l. IsList l => l -> [Item l]
toList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Array (UArray ty)
a

null :: PrimType ty => ChunkedUArray ty -> Bool
null :: forall ty. PrimType ty => ChunkedUArray ty -> Bool
null (ChunkedUArray Array (UArray ty)
array) =
    forall c. Collection c => c -> Bool
C.null Array (UArray ty)
array Bool -> Bool -> Bool
|| Offset (UArray ty) -> Bool
allNulls Offset (UArray ty)
0
  where
    !len :: CountOf (UArray ty)
len = forall a. Array a -> CountOf a
A.length Array (UArray ty)
array
    allNulls :: Offset (UArray ty) -> Bool
allNulls !Offset (UArray ty)
idx
      | Offset (UArray ty)
idx forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf (UArray ty)
len = Bool
True
      | Bool
otherwise    = forall c. Collection c => c -> Bool
C.null (Array (UArray ty)
array forall ty. Array ty -> Offset ty -> ty
`A.unsafeIndex` Offset (UArray ty)
idx) Bool -> Bool -> Bool
&& Offset (UArray ty) -> Bool
allNulls (Offset (UArray ty)
idx forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1)

-- | Returns the length of this `ChunkedUArray`, by summing each inner length.
-- Complexity: O(n) where `n` is the number of chunks, as U.length u is O(1).
length :: PrimType ty => ChunkedUArray ty -> CountOf ty
length :: forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length (ChunkedUArray Array (UArray ty)
array) = forall collection a.
Foldable collection =>
(a -> Element collection -> a) -> a -> collection -> a
C.foldl' (\CountOf ty
acc Element (Array (UArray ty))
l -> CountOf ty
acc forall a. Additive a => a -> a -> a
+ forall ty. UArray ty -> CountOf ty
U.length Element (Array (UArray ty))
l) CountOf ty
0 Array (UArray ty)
array

-- | Returns `True` if the given element is contained in the `ChunkedUArray`.
-- Complexity: O(n) where `n` is the number of chunks, as U.length u is O(1).
elem :: PrimType ty => ty -> ChunkedUArray ty -> Bool
elem :: forall ty. PrimType ty => ty -> ChunkedUArray ty -> Bool
elem ty
el (ChunkedUArray Array (UArray ty)
array) = Offset (UArray ty) -> Bool
loop Offset (UArray ty)
0
  where
    !len :: CountOf (UArray ty)
len = forall a. Array a -> CountOf a
A.length Array (UArray ty)
array
    loop :: Offset (UArray ty) -> Bool
loop Offset (UArray ty)
i
        | Offset (UArray ty)
i forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf (UArray ty)
len = Bool
False
        | Bool
otherwise  =
            case forall c a.
(Collection c, Eq a, a ~ Element c) =>
Element c -> c -> Bool
C.elem ty
el (forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array Offset (UArray ty)
i) of
                Bool
True  -> Bool
True
                Bool
False -> Offset (UArray ty) -> Bool
loop (Offset (UArray ty)
iforall a. Additive a => a -> a -> a
+Offset (UArray ty)
1)

-- | Fold a `ChunkedUArray' leftwards strictly. Implemented internally using a double
-- fold on the nested Array structure. Other folds implemented analogously.
foldl' :: PrimType ty => (a -> ty -> a) -> a -> ChunkedUArray ty -> a
foldl' :: forall ty a.
PrimType ty =>
(a -> ty -> a) -> a -> ChunkedUArray ty -> a
foldl' a -> ty -> a
f a
initialAcc (ChunkedUArray Array (UArray ty)
cua) = forall a ty. (a -> ty -> a) -> a -> Array ty -> a
A.foldl' (forall ty a. PrimType ty => (a -> ty -> a) -> a -> UArray ty -> a
U.foldl' a -> ty -> a
f) a
initialAcc Array (UArray ty)
cua

foldr :: PrimType ty => (ty -> a -> a) -> a -> ChunkedUArray ty -> a
foldr :: forall ty a.
PrimType ty =>
(ty -> a -> a) -> a -> ChunkedUArray ty -> a
foldr ty -> a -> a
f a
initialAcc (ChunkedUArray Array (UArray ty)
cua) = forall ty a. (ty -> a -> a) -> a -> Array ty -> a
A.foldr (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. (a -> b) -> a -> b
$ forall ty a. PrimType ty => (ty -> a -> a) -> a -> UArray ty -> a
U.foldr ty -> a -> a
f) a
initialAcc Array (UArray ty)
cua

minimum :: (Ord ty, PrimType ty) => C.NonEmpty (ChunkedUArray ty) -> ty
minimum :: forall ty.
(Ord ty, PrimType ty) =>
NonEmpty (ChunkedUArray ty) -> ty
minimum NonEmpty (ChunkedUArray ty)
cua = forall ty a.
PrimType ty =>
(a -> ty -> a) -> a -> ChunkedUArray ty -> a
foldl' forall a. Ord a => a -> a -> a
min (forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex ChunkedUArray ty
cua' Offset ty
0) (forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop CountOf ty
1 ChunkedUArray ty
cua')
  where
    cua' :: ChunkedUArray ty
cua' = forall a. NonEmpty a -> a
C.getNonEmpty NonEmpty (ChunkedUArray ty)
cua

maximum :: (Ord ty, PrimType ty) => C.NonEmpty (ChunkedUArray ty) -> ty
maximum :: forall ty.
(Ord ty, PrimType ty) =>
NonEmpty (ChunkedUArray ty) -> ty
maximum NonEmpty (ChunkedUArray ty)
cua = forall ty a.
PrimType ty =>
(a -> ty -> a) -> a -> ChunkedUArray ty -> a
foldl' forall a. Ord a => a -> a -> a
max (forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex ChunkedUArray ty
cua' Offset ty
0) (forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop CountOf ty
1 ChunkedUArray ty
cua')
  where
    cua' :: ChunkedUArray ty
cua' = forall a. NonEmpty a -> a
C.getNonEmpty NonEmpty (ChunkedUArray ty)
cua

-- | Equality between `ChunkedUArray`.
-- This function is fiddly to write as is not enough to compare for
-- equality the inner `UArray`(s), we need an element-by-element
-- comparison.
equal :: PrimType ty => ChunkedUArray ty -> ChunkedUArray ty -> Bool
equal :: forall ty.
PrimType ty =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
equal ChunkedUArray ty
ca1 ChunkedUArray ty
ca2 =
    CountOf ty
len1 forall a. Eq a => a -> a -> Bool
== CountOf ty
len2 Bool -> Bool -> Bool
&& Offset ty -> Bool
go Offset ty
0
  where
    len1 :: CountOf ty
len1 = forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
ca1
    len2 :: CountOf ty
len2 = forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
ca2

    go :: Offset ty -> Bool
go !Offset ty
x
      | Offset ty
x forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
len1 = Bool
True
      | Bool
otherwise   = (ChunkedUArray ty
ca1 forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
`unsafeIndex` Offset ty
x forall a. Eq a => a -> a -> Bool
== ChunkedUArray ty
ca2 forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
`unsafeIndex` Offset ty
x) Bool -> Bool -> Bool
&& Offset ty -> Bool
go (Offset ty
x forall a. Additive a => a -> a -> a
+ Offset ty
1)

-- given an offset express in element of ty, return the offset in array in the spine,
-- plus the relative offset in element on this array
findPos :: PrimType ty => Offset ty -> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
findPos :: forall ty.
PrimType ty =>
Offset ty
-> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
findPos Offset ty
absOfs (ChunkedUArray Array (UArray ty)
array)
    | forall ty. Array ty -> Bool
A.null Array (UArray ty)
array = forall a. Maybe a
Nothing
    | Bool
otherwise    = Offset ty
-> Offset (UArray ty) -> Maybe (Offset (UArray ty), Offset ty)
loop Offset ty
absOfs Offset (UArray ty)
0
  where
    !len :: CountOf (UArray ty)
len = forall a. Array a -> CountOf a
A.length Array (UArray ty)
array
    loop :: Offset ty
-> Offset (UArray ty) -> Maybe (Offset (UArray ty), Offset ty)
loop Offset ty
relOfs Offset (UArray ty)
outerI
        | Offset (UArray ty)
outerI forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf (UArray ty)
len = forall a. Maybe a
Nothing -- haven't found what to do
        | Offset ty
relOfs forall a. Eq a => a -> a -> Bool
== Offset ty
0     = forall a. a -> Maybe a
Just (Offset (UArray ty)
outerI, Offset ty
0)
        | Bool
otherwise       =
            let !innera :: UArray ty
innera   = forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array Offset (UArray ty)
outerI
                !innerLen :: CountOf ty
innerLen = forall ty. UArray ty -> CountOf ty
U.length UArray ty
innera
             in case forall ty. Offset ty -> CountOf ty -> Maybe (Offset ty)
removeArraySize Offset ty
relOfs CountOf ty
innerLen of
                        Maybe (Offset ty)
Nothing      -> forall a. a -> Maybe a
Just (Offset (UArray ty)
outerI, Offset ty
relOfs)
                        Just Offset ty
relOfs' -> Offset ty
-> Offset (UArray ty) -> Maybe (Offset (UArray ty), Offset ty)
loop Offset ty
relOfs' (Offset (UArray ty)
outerI forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1)

splitChunk :: Offset (UArray ty) -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitChunk :: forall ty.
Offset (UArray ty)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitChunk Offset (UArray ty)
ofs (ChunkedUArray Array (UArray ty)
c) = (forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray) forall a b. (a -> b) -> a -> b
$ forall ty. CountOf ty -> Array ty -> (Array ty, Array ty)
A.splitAt (forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofs) Array (UArray ty)
c

take :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
take :: forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
take CountOf ty
n c :: ChunkedUArray ty
c@(ChunkedUArray Array (UArray ty)
spine)
    | CountOf ty
n forall a. Ord a => a -> a -> Bool
<= CountOf ty
0    = forall a. ChunkedUArray a
empty
    | Bool
otherwise =
        case forall ty.
PrimType ty =>
Offset ty
-> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
findPos (forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
n) ChunkedUArray ty
c of
            Maybe (Offset (UArray ty), Offset ty)
Nothing       -> ChunkedUArray ty
c
            Just (Offset (UArray ty)
ofs, Offset ty
0) -> forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (forall ty. CountOf ty -> Array ty -> Array ty
A.take (forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofs) Array (UArray ty)
spine)
            Just (Offset (UArray ty)
ofs, Offset ty
r) ->
                let uarr :: UArray ty
uarr = forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
spine Offset (UArray ty)
ofs
                 in forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (forall ty. CountOf ty -> Array ty -> Array ty
A.take (forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofs) Array (UArray ty)
spine forall ty. Array ty -> ty -> Array ty
`A.snoc` forall ty. CountOf ty -> UArray ty -> UArray ty
U.take (forall a. Offset a -> CountOf a
offsetAsSize Offset ty
r) UArray ty
uarr)

drop :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop :: forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop CountOf ty
n c :: ChunkedUArray ty
c@(ChunkedUArray Array (UArray ty)
spine)
    | CountOf ty
n forall a. Ord a => a -> a -> Bool
<= CountOf ty
0    = ChunkedUArray ty
c
    | Bool
otherwise =
        case forall ty.
PrimType ty =>
Offset ty
-> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
findPos (forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
n) ChunkedUArray ty
c of
            Maybe (Offset (UArray ty), Offset ty)
Nothing       -> forall a. ChunkedUArray a
empty
            Just (Offset (UArray ty)
ofs, Offset ty
0) -> forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (forall ty. CountOf ty -> Array ty -> Array ty
A.drop (forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofs) Array (UArray ty)
spine)
            Just (Offset (UArray ty)
ofs, Offset ty
r) ->
                let uarr :: UArray ty
uarr = forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
spine Offset (UArray ty)
ofs
                 in forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (forall ty. CountOf ty -> UArray ty -> UArray ty
U.drop (forall a. Offset a -> CountOf a
offsetAsSize Offset ty
r) UArray ty
uarr forall ty. ty -> Array ty -> Array ty
`A.cons` forall ty. CountOf ty -> Array ty -> Array ty
A.drop (forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofsforall a. Additive a => a -> a -> a
+CountOf (UArray ty)
1) Array (UArray ty)
spine)

splitAt :: PrimType ty => CountOf ty -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitAt :: forall ty.
PrimType ty =>
CountOf ty
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitAt CountOf ty
n c :: ChunkedUArray ty
c@(ChunkedUArray Array (UArray ty)
spine)
    | CountOf ty
n forall a. Ord a => a -> a -> Bool
<= CountOf ty
0    = (forall a. ChunkedUArray a
empty, ChunkedUArray ty
c)
    | Bool
otherwise =
        case forall ty.
PrimType ty =>
Offset ty
-> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
findPos (forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
n) ChunkedUArray ty
c of
            Maybe (Offset (UArray ty), Offset ty)
Nothing       -> (ChunkedUArray ty
c, forall a. ChunkedUArray a
empty)
            Just (Offset (UArray ty)
ofs, Offset ty
0) -> forall ty.
Offset (UArray ty)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitChunk Offset (UArray ty)
ofs ChunkedUArray ty
c
            Just (Offset (UArray ty)
ofs, forall a. Offset a -> CountOf a
offsetAsSize -> CountOf ty
r) ->
                let uarr :: UArray ty
uarr = forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
spine Offset (UArray ty)
ofs
                 in ( forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (forall ty. CountOf ty -> Array ty -> Array ty
A.take (forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofs) Array (UArray ty)
spine forall ty. Array ty -> ty -> Array ty
`A.snoc` forall ty. CountOf ty -> UArray ty -> UArray ty
U.take CountOf ty
r UArray ty
uarr)
                    , forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (forall ty. CountOf ty -> UArray ty -> UArray ty
U.drop CountOf ty
r UArray ty
uarr forall ty. ty -> Array ty -> Array ty
`A.cons` forall ty. CountOf ty -> Array ty -> Array ty
A.drop (forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofsforall a. Additive a => a -> a -> a
+CountOf (UArray ty)
1) Array (UArray ty)
spine)
                    )

revTake :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revTake :: forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revTake CountOf ty
n ChunkedUArray ty
c = case forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
c forall a. Subtractive a => a -> a -> Difference a
- CountOf ty
n of
    Maybe (CountOf ty)
Difference (CountOf ty)
Nothing -> ChunkedUArray ty
c
    Just CountOf ty
elems -> forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop CountOf ty
elems ChunkedUArray ty
c

revDrop :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revDrop :: forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revDrop CountOf ty
n ChunkedUArray ty
c = case forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
c forall a. Subtractive a => a -> a -> Difference a
- CountOf ty
n of
    Maybe (CountOf ty)
Difference (CountOf ty)
Nothing -> forall a. ChunkedUArray a
empty
    Just CountOf ty
keepElems -> forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
take CountOf ty
keepElems ChunkedUArray ty
c

-- TODO: Improve implementation.
splitOn :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> [ChunkedUArray ty]
splitOn :: forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> [ChunkedUArray ty]
splitOn ty -> Bool
p = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall l. IsList l => [Item l] -> l
fromList forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall c. Sequential c => (Element c -> Bool) -> c -> [c]
C.splitOn ty -> Bool
p forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
break :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
break :: forall ty.
PrimType ty =>
(ty -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
break ty -> Bool
p = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall l. IsList l => [Item l] -> l
fromList forall l. IsList l => [Item l] -> l
fromList forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall c. Sequential c => (Element c -> Bool) -> c -> (c, c)
C.break ty -> Bool
p forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
breakEnd :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
breakEnd :: forall ty.
PrimType ty =>
(ty -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
breakEnd ty -> Bool
p = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall l. IsList l => [Item l] -> l
fromList forall l. IsList l => [Item l] -> l
fromList forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall c. Sequential c => (Element c -> Bool) -> c -> (c, c)
C.breakEnd ty -> Bool
p forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
intersperse :: PrimType ty => ty -> ChunkedUArray ty -> ChunkedUArray ty
intersperse :: forall ty.
PrimType ty =>
ty -> ChunkedUArray ty -> ChunkedUArray ty
intersperse ty
el = forall l. IsList l => [Item l] -> l
fromList forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall c. Sequential c => Element c -> c -> c
C.intersperse ty
el forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
reverse :: PrimType ty => ChunkedUArray ty -> ChunkedUArray ty
reverse :: forall ty. PrimType ty => ChunkedUArray ty -> ChunkedUArray ty
reverse = forall l. IsList l => [Item l] -> l
fromList forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall c. Sequential c => c -> c
C.reverse forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
filter :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> ChunkedUArray ty
filter :: forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> ChunkedUArray ty
filter ty -> Bool
p = forall l. IsList l => [Item l] -> l
fromList forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall c. Sequential c => (Element c -> Bool) -> c -> c
C.filter ty -> Bool
p forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
unsnoc :: PrimType ty => ChunkedUArray ty -> Maybe (ChunkedUArray ty, ty)
unsnoc :: forall ty.
PrimType ty =>
ChunkedUArray ty -> Maybe (ChunkedUArray ty, ty)
unsnoc ChunkedUArray ty
v = forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first forall l. IsList l => [Item l] -> l
fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall c. Sequential c => c -> Maybe (c, Element c)
C.unsnoc forall a b. (a -> b) -> a -> b
$ forall l. IsList l => l -> [Item l]
toList ChunkedUArray ty
v)

-- TODO: Improve implementation.
uncons :: PrimType ty => ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty)
uncons :: forall ty.
PrimType ty =>
ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty)
uncons ChunkedUArray ty
v = forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second forall l. IsList l => [Item l] -> l
fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall c. Sequential c => c -> Maybe (Element c, c)
C.uncons forall a b. (a -> b) -> a -> b
$ forall l. IsList l => l -> [Item l]
toList ChunkedUArray ty
v)

cons :: PrimType ty => ty -> ChunkedUArray ty -> ChunkedUArray ty
cons :: forall ty.
PrimType ty =>
ty -> ChunkedUArray ty -> ChunkedUArray ty
cons ty
el (ChunkedUArray Array (UArray ty)
inner) = forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray forall a b. (a -> b) -> a -> b
$ forall a. (forall s. ST s a) -> a
runST forall a b. (a -> b) -> a -> b
$ do
  let newLen :: CountOf (UArray ty)
newLen = forall c. Collection c => c -> CountOf (Element c)
C.length Array (UArray ty)
inner forall a. Additive a => a -> a -> a
+ CountOf (UArray ty)
1
  MArray (UArray ty) s
newArray   <- forall (prim :: * -> *) ty.
PrimMonad prim =>
CountOf ty -> prim (MArray ty (PrimState prim))
A.new CountOf (UArray ty)
newLen
  let single :: UArray ty
single = forall l. IsList l => [Item l] -> l
fromList [ty
el]
  forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
A.unsafeWrite MArray (UArray ty) s
newArray Offset (UArray ty)
0 UArray ty
single
  forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim)
-> Offset ty -> Array ty -> Offset ty -> CountOf ty -> prim ()
A.unsafeCopyAtRO MArray (UArray ty) s
newArray (forall ty. Int -> Offset ty
Offset Int
1) Array (UArray ty)
inner (forall ty. Int -> Offset ty
Offset Int
0) (forall c. Collection c => c -> CountOf (Element c)
C.length Array (UArray ty)
inner)
  forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim) -> prim (Array ty)
A.unsafeFreeze MArray (UArray ty) s
newArray

snoc :: PrimType ty => ChunkedUArray ty -> ty -> ChunkedUArray ty
snoc :: forall ty.
PrimType ty =>
ChunkedUArray ty -> ty -> ChunkedUArray ty
snoc (ChunkedUArray Array (UArray ty)
spine) ty
el = forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray forall a b. (a -> b) -> a -> b
$ forall a. (forall s. ST s a) -> a
runST forall a b. (a -> b) -> a -> b
$ do
  MArray (UArray ty) s
newArray  <- forall (prim :: * -> *) ty.
PrimMonad prim =>
CountOf ty -> prim (MArray ty (PrimState prim))
A.new (forall a. Array a -> CountOf a
A.length Array (UArray ty)
spine forall a. Additive a => a -> a -> a
+ CountOf (UArray ty)
1)
  let single :: UArray ty
single = forall ty. PrimType ty => ty -> UArray ty
U.singleton ty
el
  forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim)
-> Offset ty -> Array ty -> Offset ty -> CountOf ty -> prim ()
A.unsafeCopyAtRO MArray (UArray ty) s
newArray (forall ty. Int -> Offset ty
Offset Int
0) Array (UArray ty)
spine (forall ty. Int -> Offset ty
Offset Int
0) (forall c. Collection c => c -> CountOf (Element c)
C.length Array (UArray ty)
spine)
  forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
A.unsafeWrite MArray (UArray ty) s
newArray (forall a. CountOf a -> Offset a
sizeAsOffset forall a b. (a -> b) -> a -> b
$ forall a. Array a -> CountOf a
A.length Array (UArray ty)
spine) UArray ty
single
  forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim) -> prim (Array ty)
A.unsafeFreeze MArray (UArray ty) s
newArray

-- TODO optimise
find :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> Maybe ty
find :: forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> Maybe ty
find ty -> Bool
fn ChunkedUArray ty
v = Offset ty -> Maybe ty
loop Offset ty
0
  where
    len :: CountOf ty
len = forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
v
    loop :: Offset ty -> Maybe ty
loop !Offset ty
idx
      | Offset ty
idx forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
len = forall a. Maybe a
Nothing
      | Bool
otherwise    =
        let currentElem :: ty
currentElem = ChunkedUArray ty
v forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
`unsafeIndex` Offset ty
idx
        in case ty -> Bool
fn ty
currentElem of
          Bool
True  -> forall a. a -> Maybe a
Just ty
currentElem
          Bool
False -> Offset ty -> Maybe ty
loop (Offset ty
idx forall a. Additive a => a -> a -> a
+ Offset ty
1)

-- TODO: Improve implementation.
sortBy :: PrimType ty => (ty -> ty -> Ordering) -> ChunkedUArray ty -> ChunkedUArray ty
sortBy :: forall ty.
PrimType ty =>
(ty -> ty -> Ordering) -> ChunkedUArray ty -> ChunkedUArray ty
sortBy ty -> ty -> Ordering
p = forall l. IsList l => [Item l] -> l
fromList forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall c.
Sequential c =>
(Element c -> Element c -> Ordering) -> c -> c
C.sortBy ty -> ty -> Ordering
p forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall l. IsList l => l -> [Item l]
toList

index :: PrimType ty => ChunkedUArray ty -> Offset ty -> ty
index :: forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
index ChunkedUArray ty
array Offset ty
n
    | forall ty. Offset ty -> CountOf ty -> Bool
isOutOfBound Offset ty
n CountOf ty
len = forall ty a. OutOfBoundOperation -> Offset ty -> CountOf ty -> a
outOfBound OutOfBoundOperation
OOB_Index Offset ty
n CountOf ty
len
    | Bool
otherwise          = forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex ChunkedUArray ty
array Offset ty
n
  where len :: CountOf ty
len = forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
array
{-# INLINE index #-}

unsafeIndex :: PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex :: forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex (ChunkedUArray Array (UArray ty)
array) Offset ty
idx = UArray ty -> Offset (UArray ty) -> Offset ty -> ty
go (forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array Offset (UArray ty)
0) Offset (UArray ty)
0 Offset ty
idx
  where
    go :: UArray ty -> Offset (UArray ty) -> Offset ty -> ty
go UArray ty
u Offset (UArray ty)
globalIndex Offset ty
0 = case forall c. Collection c => c -> Bool
C.null UArray ty
u of
      -- Skip empty chunks.
      Bool
True  -> UArray ty -> Offset (UArray ty) -> Offset ty -> ty
go (forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array (Offset (UArray ty)
globalIndex forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1)) (Offset (UArray ty)
globalIndex forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1) Offset ty
0
      Bool
False -> forall ty. PrimType ty => UArray ty -> Offset ty -> ty
U.unsafeIndex UArray ty
u Offset ty
0
    go UArray ty
u !Offset (UArray ty)
globalIndex !Offset ty
i
      -- Skip empty chunks.
      | forall c. Collection c => c -> Bool
C.null UArray ty
u  = UArray ty -> Offset (UArray ty) -> Offset ty -> ty
go (forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array (Offset (UArray ty)
globalIndex forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1)) (Offset (UArray ty)
globalIndex forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1) Offset ty
i
      | Bool
otherwise =
          case forall ty. Offset ty -> CountOf ty -> Maybe (Offset ty)
removeArraySize Offset ty
i (forall ty. UArray ty -> CountOf ty
U.length UArray ty
u) of
              Just Offset ty
i' -> UArray ty -> Offset (UArray ty) -> Offset ty -> ty
go (forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array (Offset (UArray ty)
globalIndex forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1)) (Offset (UArray ty)
globalIndex forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1) Offset ty
i'
              Maybe (Offset ty)
Nothing -> forall ty. PrimType ty => UArray ty -> Offset ty -> ty
U.unsafeIndex UArray ty
u Offset ty
i

{-# INLINE unsafeIndex #-}

removeArraySize :: Offset ty -> CountOf ty -> Maybe (Offset ty)
removeArraySize :: forall ty. Offset ty -> CountOf ty -> Maybe (Offset ty)
removeArraySize (Offset Int
ty) (CountOf Int
s)
    | Int
ty forall a. Ord a => a -> a -> Bool
>= Int
s   = forall a. a -> Maybe a
Just (forall ty. Int -> Offset ty
Offset (Int
ty forall a. Subtractive a => a -> a -> Difference a
- Int
s))
    | Bool
otherwise = forall a. Maybe a
Nothing