project-m36-1.1.0: src/lib/ProjectM36/TupleSet.hs
module ProjectM36.TupleSet where
import ProjectM36.Base
import ProjectM36.Tuple
import ProjectM36.Error
import qualified Data.HashSet as HS
import qualified Data.Vector as V
import qualified Control.Parallel.Strategies as P
import Data.Either
emptyTupleSet :: RelationTupleSet
emptyTupleSet = RelationTupleSet []
singletonTupleSet :: RelationTupleSet
singletonTupleSet = RelationTupleSet [emptyTuple]
--ensure that all maps have the same keys and key count
verifyTupleSet :: Attributes -> RelationTupleSet -> Either RelationalError RelationTupleSet
verifyTupleSet attrs tupleSet = do
--check that all tuples have the same attributes and that the atom types match
let tupleList = map (verifyTuple attrs) (asList tupleSet) `P.using` P.parListChunk chunkSize P.r0
chunkSize = (length . asList) tupleSet `div` 24
--let tupleList = P.parMap P.rdeepseq (verifyTuple attrs) (HS.toList tupleSet)
case lefts tupleList of
x : _ -> Left x
_ -> pure $ RelationTupleSet $ (HS.toList . HS.fromList) (rights tupleList)
mkTupleSet :: Attributes -> [RelationTuple] -> Either RelationalError RelationTupleSet
mkTupleSet attrs tuples = verifyTupleSet attrs (RelationTupleSet tuples)
mkTupleSetFromList :: Attributes -> [[Atom]] -> Either RelationalError RelationTupleSet
mkTupleSetFromList attrs atomMatrix = mkTupleSet attrs $ map (mkRelationTuple attrs . V.fromList) atomMatrix
-- | Union two tuplesets while reordering their attribute/atom mapping properly.
tupleSetUnion :: Attributes -> RelationTupleSet -> RelationTupleSet -> RelationTupleSet
tupleSetUnion targetAttrs tupSet1 tupSet2 = RelationTupleSet $ HS.toList . HS.fromList $ reorder (asList tupSet1) ++ reorder (asList tupSet2)
where
reorder = map (reorderTuple targetAttrs)