summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam T <pxqr.sta@gmail.com>2013-05-20 16:07:08 +0400
committerSam T <pxqr.sta@gmail.com>2013-05-20 16:07:08 +0400
commitc31623599ee6f7fbcfc7b3a991c9a608c8c10c53 (patch)
tree5cb376b8c89684da315e62aedc2933471f1e5032 /src
parent3498b67c4dac7850d24df6a70583f5868b5a288e (diff)
~ Rename intset to bitfield
Diffstat (limited to 'src')
-rw-r--r--src/Data/Bitfield/Mutable.hs57
1 files changed, 29 insertions, 28 deletions
diff --git a/src/Data/Bitfield/Mutable.hs b/src/Data/Bitfield/Mutable.hs
index 504c4cd0..80954a2f 100644
--- a/src/Data/Bitfield/Mutable.hs
+++ b/src/Data/Bitfield/Mutable.hs
@@ -15,13 +15,13 @@
15-- * Insertion, deletion are atomic, waitfree and failfree. 15-- * Insertion, deletion are atomic, waitfree and failfree.
16-- 16--
17-- * You can avoid copying in conversion if you don't care about 17-- * You can avoid copying in conversion if you don't care about
18-- referencial transparency or sure that after conversion bitfields 18-- referencial transparency or sure that after conversion
19-- never modified. 19-- bitfields never modified.
20-- 20--
21-- 21--
22{-# OPTIONS -fno-warn-unused-do-bind #-} 22{-# OPTIONS -fno-warn-unused-do-bind #-}
23module Data.Bitfield.Mutable 23module Data.Bitfield.Mutable
24 ( IntSet 24 ( Bitfield
25 25
26 -- * Construction 26 -- * Construction
27 , empty, full 27 , empty, full
@@ -51,7 +51,7 @@ import Foreign
51 51
52 52
53-- | Basically 'BitSet' is a wrapper on the 'ForeignPtr'. 53-- | Basically 'BitSet' is a wrapper on the 'ForeignPtr'.
54data IntSet = IntSet { 54data Bitfield = Bitfield {
55 sBasePtr :: {-# UNPACK #-} !(ForeignPtr Word8) 55 sBasePtr :: {-# UNPACK #-} !(ForeignPtr Word8)
56 , sOffset :: {-# UNPACK #-} !Int 56 , sOffset :: {-# UNPACK #-} !Int
57 , sByteSize :: {-# UNPACK #-} !Int 57 , sByteSize :: {-# UNPACK #-} !Int
@@ -59,40 +59,40 @@ data IntSet = IntSet {
59 } deriving Show 59 } deriving Show
60 60
61 61
62maxSize :: IntSet -> Int 62maxSize :: Bitfield -> Int
63maxSize = sMaxSize 63maxSize = sMaxSize
64 64
65 65
66create :: Int -> (Int -> Ptr Word8 -> IO a) -> IO IntSet 66create :: Int -> (Int -> Ptr Word8 -> IO a) -> IO Bitfield
67create n f = do 67create n f = do
68 let byteSize = sizeInBytes n 68 let byteSize = sizeInBytes n
69 fptr <- mallocForeignPtrBytes byteSize 69 fptr <- mallocForeignPtrBytes byteSize
70 withForeignPtr fptr (f byteSize) 70 withForeignPtr fptr (f byteSize)
71 return (IntSet fptr 0 byteSize n) 71 return (Bitfield fptr 0 byteSize n)
72 72
73-- | Create a 'IntSet' with a given size in /bits/. 73-- | Create a 'IntSet' with a given size in /bits/.
74empty :: Int -> IO IntSet 74empty :: Int -> IO Bitfield
75empty n = create n $ \bn ptr -> 75empty n = create n $ \bn ptr ->
76 B.memset ptr 0 (fromIntegral bn) 76 B.memset ptr 0 (fromIntegral bn)
77 77
78full :: Int -> IO IntSet 78full :: Int -> IO Bitfield
79full n = create n $ \bn ptr -> 79full n = create n $ \bn ptr ->
80 B.memset ptr (error "IntSet.full") (fromIntegral bn) 80 B.memset ptr (error "IntSet.full") (fromIntegral bn)
81 81
82 82
83-- | Should be used to free scarce resources immediately. 83-- | Should be used to free scarce resources immediately.
84-- 84--
85-- WARNING: After this call 'BitField' should not be used. 85-- WARNING: After this call 'BitField' should not be used. Also you
86-- Also you can avoid using it at all if resource is not too scarce. 86-- can avoid using it at all if resource is not too scarce.
87-- 87--
88releaseIntSet :: IntSet -> IO () 88releaseIntSet :: Bitfield -> IO ()
89releaseIntSet = finalizeForeignPtr . sBasePtr 89releaseIntSet = finalizeForeignPtr . sBasePtr
90 90
91-- | Set nth bit in the given BifField to 1. 91-- | Set nth bit in the given BifField to 1.
92-- 92--
93-- UNSAFE: no bound checking. 93-- UNSAFE: no bound checking.
94-- 94--
95insertUnsafe :: Int -> IntSet -> IO () 95insertUnsafe :: Int -> Bitfield -> IO ()
96insertUnsafe i s = 96insertUnsafe i s =
97 withByte s i $ \ptr -> do 97 withByte s i $ \ptr -> do
98 fetchAndOr ptr (bit (bitLoc i)) 98 fetchAndOr ptr (bit (bitLoc i))
@@ -100,7 +100,7 @@ insertUnsafe i s =
100{-# INLINE insertUnsafe #-} 100{-# INLINE insertUnsafe #-}
101 101
102 102
103deleteUnsafe :: Int -> IntSet -> IO () 103deleteUnsafe :: Int -> Bitfield -> IO ()
104deleteUnsafe i s = 104deleteUnsafe i s =
105 withByte s i $ \ptr -> do 105 withByte s i $ \ptr -> do
106 fetchAndAnd ptr (complement (bit (bitLoc i))) 106 fetchAndAnd ptr (complement (bit (bitLoc i)))
@@ -111,38 +111,39 @@ deleteUnsafe i s =
111-- 111--
112-- UNSAFE: no bound checking. 112-- UNSAFE: no bound checking.
113-- 113--
114lookupUnsafe :: Int -> IntSet -> IO Bool 114lookupUnsafe :: Int -> Bitfield -> IO Bool
115lookupUnsafe n s = withByte s n $ \ptr -> (`testBit` bitLoc n) <$> peek ptr 115lookupUnsafe n s = withByte s n $ \ptr -> (`testBit` bitLoc n) <$> peek ptr
116{-# INLINE lookupUnsafe #-} 116{-# INLINE lookupUnsafe #-}
117 117
118fromByteString :: Int -> ByteString -> IntSet 118fromByteString :: Int -> ByteString -> Bitfield
119fromByteString n = fromByteStringUnsafe n . B.copy 119fromByteString n = fromByteStringUnsafe n . B.copy
120{-# INLINE fromByteString #-} 120{-# INLINE fromByteString #-}
121 121
122toByteString :: IntSet -> ByteString 122toByteString :: Bitfield -> ByteString
123toByteString = B.copy . toByteStringUnsafe 123toByteString = B.copy . toByteStringUnsafe
124{-# INLINE toByteString #-} 124{-# INLINE toByteString #-}
125 125
126-- | Convert a 'BitField' to the 'ByteString' /without/ copying, 126-- | Convert a 'BitField' to the 'ByteString' /without/ copying,
127-- so we can write it to a socket or a file for exsample. 127-- so we can write it to a socket or a file for exsample.
128-- 128--
129-- WARNING: Note that using the resulting 'ByteString' might (and even should) 129-- WARNING: Note that using the resulting 'ByteString' might (and
130-- BREAK REFERENCIAL TRANSPARENCY since we can change bits using 'setBitN' 130-- even should) BREAK REFERENCIAL TRANSPARENCY since we can change
131-- after the conversion. Use this function wisely and if and only if 131-- bits using 'setBitN' after the conversion. Use this function
132-- you understand the consequences, otherwise the really BAD THINGS WILL HAPPEN 132-- wisely and if and only if you understand the consequences,
133-- or use safe version instead. 133-- otherwise the really BAD THINGS WILL HAPPEN or use safe version
134-- instead.
134-- 135--
135toByteStringUnsafe :: IntSet -> ByteString 136toByteStringUnsafe :: Bitfield -> ByteString
136toByteStringUnsafe = B.fromForeignPtr <$> sBasePtr <*> pure 0 <*> sByteSize 137toByteStringUnsafe = B.fromForeignPtr <$> sBasePtr <*> pure 0 <*> sByteSize
137 138
138 139
139-- | Convert a 'ByteString' to 'BitField' /without/ copying, 140-- | Convert a 'ByteString' to 'BitField' /without/ copying, so we can
140-- so we can read it from a file or a socket. 141-- read it from a file or a socket.
141-- 142--
142-- WARNING: Please see 'toByteString' doc, the same apply to this function. 143-- WARNING: Please see 'toByteString' doc, the same apply to this function.
143-- 144--
144fromByteStringUnsafe :: Int -> ByteString -> IntSet 145fromByteStringUnsafe :: Int -> ByteString -> Bitfield
145fromByteStringUnsafe n (B.PS fptr a b) = IntSet fptr a b n 146fromByteStringUnsafe n (B.PS fptr a b) = Bitfield fptr a b n
146 147
147baseSize :: (Bits a, Integral a) => 148baseSize :: (Bits a, Integral a) =>
148 a -- ^ Base, should be power of two. 149 a -- ^ Base, should be power of two.
@@ -168,7 +169,7 @@ bitLoc :: Int -> Int
168bitLoc i = i `mod` 8 * sizeOf (error "bitLoc" :: Word8) 169bitLoc i = i `mod` 8 * sizeOf (error "bitLoc" :: Word8)
169{-# INLINE byteLoc #-} 170{-# INLINE byteLoc #-}
170 171
171withByte :: IntSet -> Int -> (Ptr Word8 -> IO a) -> IO a 172withByte :: Bitfield -> Int -> (Ptr Word8 -> IO a) -> IO a
172withByte s n action = do 173withByte s n action = do
173 let offset = sOffset s + byteLoc n 174 let offset = sOffset s + byteLoc n
174 withForeignPtr (sBasePtr s) $ \ptr -> 175 withForeignPtr (sBasePtr s) $ \ptr ->