module Storage( Store, createStore, setPref, setPrefs, getPrefs, checkPref ) where import Data.Int ( Int8 ) import Preferences ( Preference ) import qualified Data.Vector.Unboxed.Mutable as Vec data Store = Store { getPointer :: Vec.IOVector Int8 , getBallotSize :: Int } createStore :: Int -> Int -> IO Store createStore maxCapacity ballotSize = do v <- Vec.replicate (maxCapacity * ballotSize) 0 return (Store { getPointer = v , getBallotSize = ballotSize }) setPref :: Store -> Int -> Preference -> IO () setPref prefStore ballot (position,rank) = do let place = (ballot - 1) * (getBallotSize prefStore) + (position - 1) Vec.write (getPointer prefStore) place (fromIntegral rank) setPrefs :: Store -> Int -> [Preference] -> IO () setPrefs prefStore ballot prefList = do let blank = take (getBallotSize prefStore) (zip [1..] (cycle [0])) mapM_ (setPref prefStore ballot) blank mapM_ (setPref prefStore ballot) prefList getPrefs :: Store -> Int -> IO [Preference] getPrefs prefStore ballot = do let startPlace = (ballot - 1) * (getBallotSize prefStore) endPlace = startPlace + (getBallotSize prefStore) - 1 base = [startPlace .. endPlace] r0 <- mapM (Vec.read (getPointer prefStore)) base let r1 = zip [1..] (map fromIntegral r0) return (filter ((/= 0) . snd) r1) checkPref :: Store -> Int -> Preference -> IO Bool checkPref prefStore ballot (position,rank) = do let place = (ballot - 1) * (getBallotSize prefStore) + (position - 1) value <- Vec.read (getPointer prefStore) place return (value == fromIntegral rank)