on master help sign in
fix critical join functions broken in Tuple-vectorization
commitf2b923d159a87656209d89902f138fb449faafb4 authorAgentM <agentm@themactionfaction.com> dateTue 2 Jun 2015, 18:21 (11 years ago) parentf42ee21
2 files changed+39−39
ProjectM36/Attribute.hs+14−14 ProjectM36/Tuple.hs+25−25
ProjectM36/Attribute.hs+14−14
@@ -22,7 +22,7 @@ attributesFromList = V.fromList -- . L.nub
2222attributeName :: Attribute -> AttributeName
2323attributeName (Attribute name _) = name
2424
25−atomType :: Attribute -> AtomType
25+atomType :: Attribute -> AtomType
2626atomType (Attribute _ atype) = atype
2727
2828isRelationAtomType :: AtomType -> Bool
@@ -38,9 +38,9 @@ joinAttributes :: Attributes -> Attributes -> Either RelationalError Attributes
3838joinAttributes attrs1 attrs2 = if V.length (vectorUniqueify overlappingAttributes) /= V.length overlappingAttributes then
3939 Left $ TupleAttributeTypeMismatchError overlappingAttributes
4040 else
41− Right $ attrs1 V.++ otherAttributes
41+ Right $ vectorUniqueify (attrs1 V.++ attrs2)
4242 where
43− (overlappingAttributes, otherAttributes) = V.partition (\attr -> V.elem attr attrs2) attrs1
43+ overlappingAttributes = V.filter (\attr -> V.elem attr attrs2) attrs1
4444
4545addAttributes :: Attributes -> Attributes -> Attributes
4646addAttributes = (V.++)
@@ -48,22 +48,22 @@ addAttributes = (V.++)
4848deleteAttributeName :: AttributeName -> Attributes -> Attributes
4949deleteAttributeName attrName = V.filter (\attr -> attributeName attr /= attrName)
5050
51−renameAttribute :: AttributeName -> Attribute -> Attribute
51+renameAttribute :: AttributeName -> Attribute -> Attribute
5252renameAttribute newAttrName (Attribute _ typeo) = Attribute newAttrName typeo
5353
5454renameAttributes :: AttributeName -> AttributeName -> Attributes -> Attributes
5555renameAttributes oldAttrName newAttrName attrs = V.map renamer attrs
5656 where
57− renamer attr = if attributeName attr == oldAttrName then
57+ renamer attr = if attributeName attr == oldAttrName then
5858 renameAttribute newAttrName attr
59− else
59+ else
6060 attr
61−
61+
6262atomTypeForAttributeName :: AttributeName -> Attributes -> Either RelationalError AtomType
6363atomTypeForAttributeName attrName attrs = do
6464 (Attribute _ atype) <- attributeForName attrName attrs
6565 return atype
66−
66+
6767attributeForName :: AttributeName -> Attributes -> Either RelationalError Attribute
6868attributeForName attrName attrs = case V.find ((attrName ==) . attributeName) attrs of
6969 Nothing -> Left $ NoSuchAttributeNameError attrName
@@ -73,7 +73,7 @@ attributesForNames :: S.Set AttributeName -> Attributes -> Attributes
7373attributesForNames attrNameSet attrs = V.filter filt attrs
7474 where
7575 filt attr = S.member (attributeName attr) attrNameSet
76−
76+
7777attributeNameSet :: Attributes -> S.Set AttributeName
7878attributeNameSet attrVec = S.fromList $ V.toList $ V.map (\(Attribute name _) -> name) attrVec
7979
@@ -95,13 +95,13 @@ matchingAttributeNameSet = S.intersection
9595-- this is sorted so the tuples know in which order to output- the ordering is arbitrary
9696sortedAttributeNameList :: S.Set AttributeName -> [AttributeName]
9797sortedAttributeNameList attrNameSet= L.sort $ S.toList attrNameSet
98−
98+
9999-- take two attribute sets and return an attribute set with the attributes which do not match
100−attributesDifference :: Attributes -> Attributes -> Attributes
100+attributesDifference :: Attributes -> Attributes -> Attributes
101101attributesDifference attrsA attrsB = V.fromList $ diff (V.toList attrsA) (V.toList attrsB)
102102 where
103103 diff a b = (a L.\\ b) ++ (b L.\\ a)
104−
104+
105105vectorUniqueify :: (Hash.Hashable a, Eq a) => V.Vector a -> V.Vector a
106106vectorUniqueify vecIn = V.fromList $ HS.toList $ HS.fromList $ V.toList vecIn
107107
@@ -113,6 +113,6 @@ verifyAttributes attrs = if collapsedAttrs /= attrs then
113113 Right attrs
114114 where
115115 collapsedAttrs = vectorUniqueify attrs
116−
116+
117117attributesEqual :: Attributes -> Attributes -> Bool
118−attributesEqual attrs1 attrs2 = V.null (attributesDifference attrs1 attrs2)
118+attributesEqual attrs1 attrs2 = V.null (attributesDifference attrs1 attrs2)
ProjectM36/Tuple.hs+25−25
@@ -21,20 +21,20 @@ tupleAttributeNameSet (RelationTuple tupAttrs _) = S.fromList $ V.toList $ V.map
2121
2222tupleAttributes :: RelationTuple -> Attributes
2323tupleAttributes (RelationTuple tupAttrs _) = tupAttrs
24−
25−-- return atoms in some arbitrary but consistent key order
24+
25+-- return atoms in some arbitrary but consistent key order
2626tupleAtoms :: RelationTuple -> V.Vector Atom
2727tupleAtoms (RelationTuple _ tupVec) = tupVec
2828
2929atomForAttributeName :: AttributeName -> RelationTuple -> Either RelationalError Atom
3030atomForAttributeName attrName (RelationTuple tupAttrs tupVec) = case V.findIndex (\attr -> attributeName attr == attrName) tupAttrs of
3131 Nothing -> Left $ NoSuchAttributeNameError attrName
32− Just index -> case tupVec V.!? index of
32+ Just index -> case tupVec V.!? index of
3333 Nothing -> Left $ NoSuchAttributeNameError attrName
3434 Just atom -> Right atom
35−
36−{- -- resolve naming clash with Attribute and Relation later
37−atomTypeForAttributeName :: AttributeName -> RelationTuple -> Either RelationalError Atom
35+
36+{- -- resolve naming clash with Attribute and Relation later
37+atomTypeForAttributeName :: AttributeName -> RelationTuple -> Either RelationalError Atom
3838atomTypeForAttributeName attrName tup = do
3939 atom <- atomForAttributeName attrName tup
4040 return $ atomTypeForAtom atom
@@ -46,15 +46,15 @@ atomsForAttributeNames attrNames tuple = V.foldr folder V.empty attrNames
4646 folder attrName acc = case atomForAttributeName attrName tuple of
4747 Left _ -> acc
4848 Right atom -> V.snoc acc atom
49−
49+
5050relationForAttributeName :: AttributeName -> RelationTuple -> Either RelationalError Relation
5151relationForAttributeName attrName tuple = do
5252 aType <- atomTypeForAttributeName attrName (tupleAttributes tuple)
5353 if not (isRelationAtomType aType) then
54− Left $ AttributeIsNotRelationValuedError attrName
55− else do
54+ Left $ AttributeIsNotRelationValuedError attrName
55+ else do
5656 atomVal <- atomForAttributeName attrName tuple
57− relationForAtom atomVal
57+ relationForAtom atomVal
5858
5959--in case the oldattr does not exist in the tuple, then return the old tuple
6060tupleRenameAttribute :: AttributeName -> AttributeName -> RelationTuple -> RelationTuple
@@ -81,21 +81,21 @@ singleTupleSetJoin tup tupSet = HS.foldr tupleJoiner HS.empty tupSet
8181-- the keys/values don't need to be resorted
8282-- if the keys share some keys and values, then merge the tuples
8383singleTupleJoin :: RelationTuple -> RelationTuple -> Maybe RelationTuple
84−singleTupleJoin tup1@(RelationTuple tupAttrs1 _) tup2@(RelationTuple tupAttrs2 _) = if
84+singleTupleJoin tup1@(RelationTuple tupAttrs1 _) tup2@(RelationTuple tupAttrs2 _) = if
8585 V.null keysIntersection || atomsForAttributeNames keysIntersection tup1 /= atomsForAttributeNames keysIntersection tup2
8686 then
8787 Nothing
88− else
88+ else
8989 Just $ RelationTuple newAttrs newVec
9090 where
9191 keysIntersection = V.map attributeName attrsIntersection
92− attrsIntersection = V.filter (flip V.notElem $ tupAttrs1) tupAttrs2
92+ attrsIntersection = V.filter (flip V.elem $ tupAttrs1) tupAttrs2
9393 newAttrs = vectorUnion tupAttrs1 tupAttrs2
9494 newVec = V.map (findAtomForAttributeName . attributeName) newAttrs
95− --search both tuples for the
95+ --search both tuples for the
9696 findAtomForAttributeName attrName = head $ rights $ fmap (atomForAttributeName attrName) [tup1, tup2]
97−
98−--same consideration as Data.List.union- duplicates in v1 are not de-duped
97+
98+--same consideration as Data.List.union- duplicates in v1 are not de-duped
9999vectorUnion :: (Eq a) => V.Vector a -> V.Vector a -> V.Vector a
100100vectorUnion v1 v2 = V.foldr folder v1 v2
101101 where
@@ -110,18 +110,18 @@ tupleExtend (RelationTuple tupAttrs1 tupVec1) (RelationTuple tupAttrs2 tupVec2)
110110 where
111111 newAttrs = tupAttrs1 V.++ tupAttrs2
112112 newVec = tupVec1 V.++ tupVec2
113−
113+
114114tupleAtomExtend :: AttributeName -> Atom -> RelationTuple -> RelationTuple
115115tupleAtomExtend newAttrName atom tupIn = tupleExtend tupIn newTup
116116 where
117117 newTup = RelationTuple (V.singleton $ Attribute newAttrName (atomTypeForAtom atom)) (V.singleton atom)
118118
119−{- sort the associative list to match the header sorting -}
119+{- sort the associative list to match the header sorting -}
120120tupleSortedAssocs :: RelationTuple -> [(AttributeName, Atom)]
121121tupleSortedAssocs (RelationTuple tupAttrs tupVec) = V.toList $ V.map (\(index,attr) -> (attributeName attr, tupVec V.! index)) $ V.indexed tupAttrs
122−
122+
123123--this could be cheaper- it may not be wortwhile to update all the tuples for projection, but then the attribute management must be slightly different- perhaps the attributes should be a vector of association tuples [(name, index)]
124−tupleProject :: S.Set AttributeName -> RelationTuple -> RelationTuple
124+tupleProject :: S.Set AttributeName -> RelationTuple -> RelationTuple
125125tupleProject projectAttrs (RelationTuple attrs tupVec) = RelationTuple newAttrs newTupVec
126126 where
127127 deleteIndices = V.findIndices (\attr -> S.notMember (attributeName attr) projectAttrs) attrs
@@ -136,14 +136,14 @@ tupleIntersection tuple1 tuple2 = RelationTuple newAttrs newTupVec
136136 where
137137 attrs1 = tupleAttributes tuple1
138138 attrs2 = tupleAttributes tuple2
139− matchingIndices = V.findIndices (\attr -> V.elem attr attrs2 &&
139+ matchingIndices = V.findIndices (\attr -> V.elem attr attrs2 &&
140140 atomForAttributeName (attributeName attr) tuple1 ==
141141 atomForAttributeName (attributeName attr) tuple2
142142 ) attrs1
143143 indexFilter = V.ifilter (\index _ -> V.elem index matchingIndices)
144144 newAttrs = indexFilter attrs1
145145 newTupVec = indexFilter (tupleAtoms tuple1)
146−
146+
147147updateTuple :: (M.Map AttributeName Atom) -> RelationTuple -> RelationTuple
148148updateTuple updateMap (RelationTuple attrs tupVec) = RelationTuple attrs newVec
149149 where
@@ -156,9 +156,9 @@ tupleToMap :: RelationTuple -> (M.Map AttributeName Atom)
156156tupleToMap (RelationTuple attrs tupVec) = M.fromList assocList
157157 where
158158 assocList = V.toList $ V.map (\(index, attr) -> (attributeName attr, tupVec V.! index)) (V.indexed attrs)
159−
159+
160160verifyTuple :: Attributes -> RelationTuple -> Either RelationalError RelationTuple
161−verifyTuple attrs tuple = let attrsTypes = V.map atomType attrs
161+verifyTuple attrs tuple = let attrsTypes = V.map atomType attrs
162162 tupleTypes = V.map atomTypeForAtom (tupleAtoms tuple) in
163163 if V.length attrs /= V.length tupleTypes then
164164 Left $ TupleAttributeCountMismatchError 0
@@ -168,7 +168,7 @@ verifyTuple attrs tuple = let attrsTypes = V.map atomType attrs
168168 else
169169 Right $ tuple
170170
171−--two tuples can be equal but the vectors of attributes could be out-of-order
171+--two tuples can be equal but the vectors of attributes could be out-of-order
172172--reorder if necessary- this is useful during relMogrify so that all the relation's tuples have identical atom/attribute ordering
173173reorderTuple :: Attributes -> RelationTuple -> RelationTuple
174174reorderTuple attrs tupIn = if tupleAttributes tupIn == attrs then