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) if not (null (lefts tupleList)) then Left $ head (lefts tupleList) else return $ 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)