rightfold / purescript-bytestrings

Immutable packed byte sequences.
https://pursuit.purescript.org/packages/purescript-bytestrings
BSD 3-Clause "New" or "Revised" License
9 stars 9 forks source link

Add bytestring slices #13

Open rightfold opened 5 years ago

rightfold commented 5 years ago

To facilitate efficient programming, there should be the following module. This should reduce the amount of copying of data. Like the Data.ByteString module, it should export many useful functions, and document their time complexities (which should never be worse here than there, I think).

module Data.ByteString.Slice
  ( ByteSlice -- don't export ctor
  , toByteString
  , fromByteString
  , take
  , drop
  -- etc
  ) where

import Data.ByteString (ByteString)

import Data.ByteString as ByteString

data ByteSlice = S ByteString Int Int

toByteString :: ByteSlice -> ByteString
toByteString (S bs begin end)
  | begin == 0 && end == ByteString.size bs = bs
  | otherwise = -- copy the portion of the bytestring

fromByteString :: ByteString -> ByteSlice
fromByteString bs = S bs 0 (ByteString.size bs)

-- Constant time!
take :: Int -> ByteSlice -> ByteSlice
take n (S bs begin end) =
  S bs begin (max begin (end - n))

-- drop is similar.

The Haskell bytestring package also does this (although it's built into ByteString there, maybe we should also do that in this package). See also: D, Go, Rust, Swift.

rightfold commented 5 years ago

Actually, yes, I think it is better to just bake this into ByteString. Otherwise the API has to be duplicated which is annoying.

That would make it AJI-incompatible with the existing version, since coercing to Buffer no longer works. But I think that's worth it; people should use unsafeFreeze and unsafeThaw, really.