{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances -fbang-patterns #-} module Data.CompactMap.Types where import Control.Monad import Foreign import Foreign.Storable import Foreign.C --import Data.Generics hiding ((:+:),GT) import Data.Char import Data.Int import Data.Binary import Data.Binary.Put --import Data.Binary.Get (getInthost) import Data.ByteString.Internal (memcmp,inlinePerformIO) import qualified Data.ByteString.Unsafe as B --import qualified Data.CompactString as C --import qualified Data.CompactString.Unsafe as C import GHC.IOBase hiding (Buffer) import GHC.Exts import GHC.Int data Buffer = Buffer { bufferData :: {-# UNPACK #-} !(IORef (ForeignPtr ())) , bufferOld :: {-# UNPACK #-} !(IORef [ForeignPtr ()]) , bufferPos :: {-# UNPACK #-} !FastMutInt , bufferSize :: {-# UNPACK #-} !FastMutInt } -- Strict, unboxed IORef data FastMutInt = FastMutInt (MutableByteArray# RealWorld) newFastMutInt (I# i) = IO $ \s -> case newByteArray# size s of (# s, arr #) -> case writeIntArray# arr 0# i s of s -> (# s, FastMutInt arr #) where I# size = sizeOf (0::Int) readFastMutInt (FastMutInt arr) = IO $ \s -> case readIntArray# arr 0# s of { (# s, i #) -> (# s, I# i #) } writeFastMutInt (FastMutInt arr) (I# i) = IO $ \s -> case writeIntArray# arr 0# i s of { s -> (# s, () #) } {- newtype OptInt = OptInt Int deriving (Eq,Ord,Enum,Typeable,Num,Show) instance Binary OptInt where {-# INLINE put #-} put (OptInt i) = putInthost i {-# INLINE get #-} get = liftM OptInt getInthost -} {- data RawString = RawString {-# UNPACK #-} !Int {-# UNPACK #-} !(Ptr CChar) instance Binary RawString where put (RawString len ptr) = error "put not defined" -- putCString (ptr,len) get = error "get not defined" {-do bs <- get return $! RawString (B.length bs) (unsafePerformIO $ B.unsafeUseAsCString bs return) -} instance Ord RawString where {-# INLINE compare #-} compare (RawString len1 ptr1) (RawString len2 ptr2) = inlinePerformIO $ do n <- memcmp (castPtr $ ptr1) (castPtr ptr2) (fromIntegral $ min len1 len2) return $! case n `compare` 0 of EQ -> compare len1 len2 x -> x instance Show RawString where show (RawString len ptr) = show (unsafePerformIO $ B.unsafePackCStringLen (ptr,len)) instance Eq RawString where a == b = compare a b == EQ -} {- instance C.Encoding a => Binary (C.CompactString a) where {-# INLINE put #-} put = put . C.toByteString {-# INLINE get #-} get = fmap C.unsafeFromByteString get -} data KeyCursor data DataCursor data Index = Index { indexStart :: {-# UNPACK #-} !(Ptr IndexItem) , indexBuffer :: {-# UNPACK #-} !Buffer } data IndexItem = IndexItem {-# UNPACK #-} !(Ptr IndexItem) {-# UNPACK #-} !(Ptr ()) {-# UNPACK #-} !(Ptr KeyCursor) {-# UNPACK #-} !(Ptr IndexItem) {-# UNPACK #-} !(Ptr IndexItem) -- Top, size, elem idx, left, right type IdxInt = Ptr IndexItem {-# INLINE extractField #-} -- Get field 'f' out of the n'th IndexItem. extractField :: Int -> (Ptr IndexItem) -> IO (Ptr IndexItem) extractField !f !ptr = do v <- peekByteOff ptr ((sizeOf (undefined::IdxInt) * f)) return (v::IdxInt) {-# INLINE putField #-} -- Put field 'f' in the n'th IndexItem putField :: Int -> (Ptr IndexItem) -> Ptr IndexItem -> IO () putField !f !ptr !v = pokeByteOff ptr ((sizeOf (undefined::IdxInt) * f)) (v :: IdxInt) instance Storable IndexItem where sizeOf _ = sizeOf (undefined :: IdxInt) * 5 alignment _ = alignment (undefined :: IdxInt) {-# INLINE peek #-} peek ptr = let ptr' = castPtr ptr get n = (peekElemOff ptr' n :: IO (Ptr a)) in liftM5 IndexItem (get 0) (get 1) (get 2) (get 3) (get 4) {-# INLINE poke #-} poke ptr' (IndexItem a b c d e) = let ptr = castPtr ptr' put n v = pokeElemOff ptr n v in put 0 a >> put 1 b >> put 2 c >> put 3 d >> put 4 e