<commit_before>{-# LANGUAGE CPP #-}
{-# LANGUAGE Rank2Types, BangPatterns #-}

-- |
-- Module      : Data.SmallArray
-- Copyright   : (c) <NAME> 2009
--               (c) <NAME> 2010
--
-- License     : BSD-style
-- Maintainer  : <EMAIL>
-- Stability   : experimental
-- Portability : portable
--
-- Packed, unboxed, heap-resident arrays.  Suitable for performance
-- critical use, both in terms of large data quantities and high
-- speed.
--
-- This module is intended to be imported @qualified@, to avoid name
-- clashes with "Prelude" functions, e.g.
--
-- > import qualified Data.SmallArray as A
--
-- The names in this module resemble those in the 'Data.Array' family
-- of modules, but are shorter due to the assumption of qualifid
-- naming.
module Data.SmallArray.Internal where

import Prelude hiding (length)
import qualified Prelude

import Control.Exception (assert)
import Control.Monad.ST

import qualified Data.ByteArray as B
import Data.ByteArray (ByteArray, MutableByteArray)

import Data.Int
import Data.Word

import Control.DeepSeq

newtype Array a
    = A ByteArray

newtype MArray s a
    = M (MutableByteArray s)

instance NFData (Array a) where
    rnf (A ary) = rnf ary

instance NFData (MArray s a) where
    rnf (M ary) = rnf ary

instance (Show e, Elt e) => Show (Array e) where
    show = show . toList

instance (Eq a, Elt a) => Eq (Array a) where
    (==) = eqArray

eqArray :: (Eq a, Elt a) => Array a -> Array a -> Bool
eqArray a b
        = let an = length a
              bn = length b
          in
            an == bn && and [unsafeIndex a n == unsafeIndex b n | n <- [0..bn-1] ]
{-# INLINE eqArray #-}

instance (Ord a, Elt a) => Ord (Array a) where
    a `compare` b
        = f 0

     where an = length a
           bn = length b
           maxLen = an `min` bn

           f n | n < maxLen
                   = case unsafeIndex a n `compare` unsafeIndex b n of
                       EQ -> f (n+1)
                       x  -> x
               | an > bn
                   = GT
               | bn > an
                   = LT
               | otherwise
                   = EQ
    {-# INLINE compare #-}

class IArray a where
    length :: a -> Int
    {-# INLINE length #-}

instance Elt a => IArray (Array a) where
    length = arrayLen

arrayLen :: Elt a => Array a -> Int<commit_msg>speed up Eq and Ord for Word8<commit_after>{-# LANGUAGE CPP #-}
{-# LANGUAGE Rank2Types, BangPatterns #-}

-- |
-- Module      : Data.SmallArray
-- Copyright   : (c) <NAME> 2009
--               (c) <NAME> 2010
--
-- License     : BSD-style
-- Maintainer  : <EMAIL>
-- Stability   : experimental
-- Portability : portable
--
-- Packed, unboxed, heap-resident arrays.  Suitable for performance
-- critical use, both in terms of large data quantities and high
-- speed.
--
-- This module is intended to be imported @qualified@, to avoid name
-- clashes with "Prelude" functions, e.g.
--
-- > import qualified Data.SmallArray as A
--
-- The names in this module resemble those in the 'Data.Array' family
-- of modules, but are shorter due to the assumption of qualifid
-- naming.
module Data.SmallArray.Internal where

import Prelude hiding (length)
import qualified Prelude

import Control.Exception (assert)
import Control.Monad.ST

import qualified Data.ByteArray as B
import Data.ByteArray (ByteArray, MutableByteArray)

import Data.Int
import Data.Word

import Control.DeepSeq

newtype Array a
    = A ByteArray

newtype MArray s a
    = M (MutableByteArray s)

instance NFData (Array a) where
    rnf (A ary) = rnf ary

instance NFData (MArray s a) where
    rnf (M ary) = rnf ary

instance (Show e, Elt e) => Show (Array e) where
    show = show . toList

instance (Eq a, Elt a) => Eq (Array a) where
    {-# SPECIALIZE instance Eq (Array Word8) #-}
    (==) = eqArray

eqArray :: (Eq a, Elt a) => Array a -> Array a -> Bool
eqArray a b
        = let an = length a
              bn = length b
          in
            an == bn && and [unsafeIndex a n == unsafeIndex b n | n <- [0..bn-1] ]
{-# INLINE eqArray #-}

instance (Ord a, Elt a) => Ord (Array a) where
    {-# SPECIALIZE instance Ord (Array Word8) #-}
    a `compare` b
        = f 0

     where an = length a
           bn = length b
           maxLen = an `min` bn

           f n | n < maxLen
                   = case unsafeIndex a n `compare` unsafeIndex b n of
                       EQ -> f (n+1)
                       x  -> x
               | an > bn
                   = GT
               | bn > an
                   = LT
               | otherwise
                   = EQ
    {-# INLINE compare #-}

class IArray a where
    length :: a -> Int
    {-# INLINE length #-}

instance Elt a => IArray (Array a) where
    length = arrayLen

arrayLen :: Elt a => Array a -> Int
{'fraction_non_alphanumeric': 0.10810810810810811, 'fraction_numerical': 0.006075843285145611, 'mean_word_length': 1.912751677852349, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2614995', 'n_tokens_mistral': 1556, 'n_tokens_neox': 1479, 'n_words': 579}