HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Simple Haskell key value file store

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
filesimplevaluestorehaskellkey

Problem

As an exercise in learning Haskell, I implemented a simple key value store, where you can put and get values (as ByteStrings). (For reference this is inspired by this short note describing bitcask's design). I'd appreciate feedback on any aspect (style, 'haskellyness', library usage etc.) of my implementation:

```
{-# LANGUAGE OverloadedStrings #-}

module KV (
evalKV,
putKV,
getKV,
liftIO
) where

import Prelude hiding (mapM)
import Data.Traversable (mapM)
import Control.Monad (liftM, liftM2)
import Control.Monad.State (StateT, evalStateT, get, put, liftIO)
import qualified System.IO as IO
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as L
import qualified Data.Binary as B
import qualified Data.Binary.Get as G
import qualified Data.Map as M

type Header = (Integer, Integer)
-- keysize valuesize

type ValueInfo = (Integer, Integer)
-- offset valuesize

type Key = ByteString

type Pair = (Key, ValueInfo)

type Index = M.Map Key ValueInfo

data KVState = KVState
{ kvHandle :: IO.Handle
, kvIndex :: Index
} deriving (Show)

type KV a = StateT KVState IO a

evalKV :: FilePath -> KV a -> IO a
evalKV p s = IO.withBinaryFile p IO.ReadWriteMode $ \h -> do
i ByteString -> KV ()
putKV k v = do
(KVState h i) KV (Maybe ByteString)
getKV k = do
(KVState h i) (Header, Integer)
readHeader c = (h, fromIntegral o)
where (h, _, o) = G.runGetState B.get c 0

readAt :: IO.Handle -> Integer -> Integer -> IO ByteString
readAt h o sz = do
IO.hSeek h IO.AbsoluteSeek o
L.hGet h $ fromIntegral sz

readPair :: IO.Handle -> Integer -> IO (Maybe Pair)
readPair h o = do
IO.hSeek h IO.AbsoluteSeek o
b ByteString -> ByteString -> IO ValueInfo
writePair h k v = do
IO.hSeek h IO.SeekFromEnd 0
let l = fromIntegral . L.length
let vsz = l v
let t = (l k, vsz) :: Header
L.hPut h (B.encode t)
L.hPut h k
p IO Index
readIndex h =

Solution

Why not:

type KeySize   = Integer
type ValueSize = Integer
type Header    = (KeySize, ValueSize)


Instead of commenting, like you did here:

type Header    = (Integer, Integer)
               -- keysize  valuesize


Same about ValueInfo.

Code Snippets

type KeySize   = Integer
type ValueSize = Integer
type Header    = (KeySize, ValueSize)
type Header    = (Integer, Integer)
               -- keysize  valuesize

Context

StackExchange Code Review Q#9177, answer score: 2

Revisions (0)

No revisions yet.