/* ---- This file is part of SECONDO. Copyright (C) 2004, University in Hagen, Department of Computer Science, Database Systems for New Applications. SECONDO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. SECONDO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SECONDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---- //paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}] //[TOC] [\tableofcontents] [1] Header File of the Spatiotemporal Group Pattern Algebra JAN, 2010 Mahmoud Sakr [TOC] 1 Overview 2 Defines and includes */ #ifndef GPATTERNALGEBRA_H_ #define GPATTERNALGEBRA_H_ #include "Algebra.h" #include "NestedList.h" #include "QueryProcessor.h" #include "StandardTypes.h" #include "LogMsg.h" #include "NList.h" #include "ListUtils.h" #include "Algebras/Relation-C++/RelationAlgebra.h" #include "Algebras/Temporal/TemporalAlgebra.h" #include "Algebras/STPattern/STPatternAlgebra.h" #include "Algebras/Spatial/SpatialAlgebra.h" #include "Algebras/Collection/CollectionAlgebra.h" #include "MSet.h" #include #include #include #include "LightWeightGraph.h" #include "Boids/Boid.h" typedef datetime::DateTime Instant; extern NestedList *nl; extern QueryProcessor* qp; namespace GPattern { enum quantifier {exactly, atleast}; struct Int64Interval { int64_t start, end; bool lc, rc; Int64Interval(int64_t s, int64_t e, bool l, bool r): start(s), end(e), lc(l), rc(r){} void Set(int64_t s, int64_t e, bool l, bool r){ start=s; end=e; lc=l; rc=r; } bool Inside(int64_t s, int64_t e, bool l, bool r) { return ((s< start && e > end) || (s== start && (l || !lc) && e > end) || (s< start && e == end && (r || !rc)) || (s== start && (l || !lc) && e == end && (r || !rc))); } bool Inside(Int64Interval& arg) { return ((arg.start< start && arg.end > end) || (arg.start== start && (arg.lc || !lc) && arg.end > end) || (arg.start< start && arg.end == end && (arg.rc || !rc)) || (arg.start== start &&(arg.lc || !lc)&& arg.end == end &&(arg.rc || !rc))); } }; /* Class ChangeRecord. Used in the process of finding LargeConnectedComponents given a ConnectedComponent */ class ChangeRecord { public: enum StatusCode{NotChanged=0, ElemsRemoved=1, UnitRemoved=2}; StatusCode status; std::vector removedNodes; std::vector removedNodesInRemoved; ChangeRecord(); bool UpdateStatus(StatusCode newCode); bool AppendToRemovedNodes(int node); std::ostream& Print(std::ostream& os); void Clear(); }; class MSetIndex { public: struct NodeLogEntry { int64_t starttime, endtime; std::list::iterator startUnitIt, endUnitIt; int startUnitIndex, endUnitIndex; std::set associatedEdges; NodeLogEntry( int64_t st, std::list::iterator stIt, int sUI, std::set& aE); std::ostream& Print(std::ostream& os); }; struct NodeLog { std::list log; void Append(std::list::iterator& usetIt, int usetIndex, std::set& edges); bool RemoveUnit(int index); std::ostream& Print(std::ostream& os); }; std::map nodes; std::vector units; MSetIndex(mset::CompressedInMemMSet& mset, std::vector >& edge2Nodes ); void ConstructIndex( mset::CompressedInMemMSet& mset, std::vector >& edge2Nodes); bool RemoveShortNodeEntries(int64_t dMS, std::vector& AllChanges); bool RemoveShortNodeEntries(int64_t dMS, std::map::iterator nodeIt, std::vector& AllChanges); void DeleteNodePart(std::map::iterator& nodeIt, std::list::iterator nodeEntryIt, std::vector& AllChanges); bool RemoveSmallUnits(int n, std::vector& AllChanges); void RemoveUnit(int index, std::vector& AllChanges); void FinalizeIndex(std::set& nodesToBeFinalized, std::list::iterator endIt); std::ostream& Print(std::ostream& os); private: void AppendInsertionsIntoNodeLog(std::set& deltaNodes, std::vector >& edge2nodesMap, std::list::iterator& curUSet, int curUSetIndex); void AppendRemovalsIntoNodeLog(std::set& deltaNodes, std::vector >& edge2nodesMap, std::list::iterator& curUSet, int curUSetIndex); }; class CheckRemoveEntry { private: int nodeId; std::vector* AllChanges; MSetIndex* index; int64_t dMS; public: static bool changed; void SetChanged(bool ch); bool GetChanged(); CheckRemoveEntry( int id, std::vector& ch, MSetIndex* i, int64_t _dMS); bool operator() (MSetIndex::NodeLogEntry& logEntry); }; /* GPatternHelper */ class GPatternHelper { public: GPatternHelper(){} ~GPatternHelper() {} bool setCompareDesc (std::set& i,std::set& j); void RemoveDuplicates(std::list& resStream); void removeShortUnits(temporalalgebra::MBool &mbool, int64_t dMS); bool RemoveShortNodeMembership(mset::CompressedInMemMSet& Accumlator, std::vector >& edge2nodesMap, int64_t dMS); std::ostream& PrintNodeHistory( std::map::iterator, std::set > >* nodeHistory, std::ostream &os ); bool CheckRemoveNodeMembership( std::map::iterator, std::set > >* nodeHistory, std::set removedEdges, std::vector >& edge2nodesMap, std::list::iterator& cur, std::set& deltaNodes, int64_t dMS); void InPlaceSetDifference(std::set& set1, std::set& set2); void InsertInNodeHistory( std::map::iterator, std::set > >* nodeHistory, std::set newEdges, std::vector >& edge2nodesMap, std::list::iterator& cur, std::set& deltaNodes); void FindNodeEdges( int newNode, std::set& newEdges, std::vector >& edge2nodesMap, std::set& newNodeEdges); bool RemoveUnitsHavingFewNodes( mset::CompressedInMemMSet& Accumlator, std::vector >& edge2nodesMap, int n); void FindLargeDynamicComponents(mset::CompressedInMemMSet& Accumlator, std::list::iterator begin, std::list::iterator end , std::vector >& edge2nodesMap, int64_t dMS, int n, std::string& qts, std::list*& finalResStream, int depth); mset::CompressedMSet* CollectResultParts( std::vector& ResultParts, std::vector& partIndexs); void FindDynamicComponents(mset::CompressedInMemMSet& Accumlator, std::list::iterator begin, std::list::iterator end , std::vector >& edge2nodesMap, int64_t dMS, int n, std::string& qts, std::list*& FinalResultStream); bool SetIntersects(std::set &set1, std::set &set2); void CheckAdd( LWGraph* g, NewComponent& comp, int n , std::list* components, std::map::iterator>& compLabelsMap, int& NextComponentLabel); void UpdateMerge(LWGraph *g, NewComponent& newComp, std::set& newEdges, std::vector >& edge2nodesMap, std::list* components, std::map::iterator>& compLabelsMap); void MergeComponents(LWGraph* g, NewComponent& newComp, std::list* components, std::map::iterator>& compLabelsMap, int& NextComponentLabel); void UpdateRemove(LWGraph* graph, std::list* components, std::map::iterator>& compLabelsMap, std::vector >& edge2nodesMap, int n, int& NextComponentLabel, std::set< int>& affectedComponentsLabels); void Finalize(LWGraph* graph, std::list* components, int64_t dMS, mset::CompressedInMemUSet& cur, std::vector& ResultParts, std::list > *ResultStream, std::list* FinalResultStream, std::vector >& edge2nodesMap); void DynamicGraphAppend(LWGraph* graph, std::list* components, std::map::iterator>& compLabelsMap, std::list::iterator cur, std::vector >& edge2nodesMap, int64_t dMS, int n, std::string& qts, int& NextComponentLabel, std::vector* ResultParts, std::list >* ResultStream, std::list*& FinalResultStream); void GraphNodes2Edges(std::set& subGraphNodes, std::set& graphEdges, std::vector >& edge2Nodes, std::set& res); bool Merge(mset::CompressedInMemMSet *_mset, std::set *subGraph, int64_t starttime, int64_t endtime, bool lc, bool rc); void SetAddRemove(std::set& _set, std::set& _add, std::set& _remove); void EdgeSet2NodeSet( std::set &edges, std::set &nodes, std::vector > edge2nodesMap); mset::CompressedMSet* EdgeMSet2NodeMSet( mset::CompressedMSet* edgeMSet, std::vector >& edge2nodesMap); void ComputeAddSubSets(mset::InMemMSet& acc, std::list::iterator t1, std::list::iterator t2, unsigned int n, int64_t dMS, std::vector* result); bool ApplyThresholds(MSetIndex& index, int n, int64_t dMS, std::vector& Changes, bool debugme); void UpdateResult(mset::CompressedInMemMSet* curMSet, std::vector >& edge2nodesMap,int n, int64_t dMS, std::string qts, std::vector& Changes, std::list& resStream, bool debugme); void ApplyChanges(mset::CompressedInMemMSet* msetPart, std::vector& changesPart, std::vector >& edge2nodesMap,int n, int64_t dMS, std::string qts, std::list& resStream, std::list& msetParts, std::list >& changeParts, bool debugme); /* Private members */ private: void GenerateAllCombinations(mset::InMemUSet& cand, int select, std::vector< std::set > & res); void AddAllSubSetsToVector(mset::InMemUSet& candidates, int64_t startInstant, int64_t curInstant, bool lc, bool rc, int n, std::multimap< std::set, Int64Interval>& res); }; class GPatternSolver { public: Supplier TheStream; /* The list of supported assignments */ std::vector< std::vector< std::pair< temporalalgebra::Interval, mset::MSet* > > > SA; std::vector Agenda; /* A helper data structure to translate the string aliases into their integer position in the Agenda, SA and ConstraintGeraph. */ std::map VarAliasMap; std::vector< std::vector< std::vector > >ConstraintGraph; std::vector ToDelete; /* The total number of variables in the CSP. */ int count; /* The iterator is used in the "start" and "end" operators to iterate over the SA */ int iterator; temporalalgebra::Interval nullInterval; /* A list of the variable that have been consumed so far. */ std::vector assignedVars; GPatternSolver():count(0),iterator(-1), nullInterval(Instant(0,0, datetime::instanttype ), Instant(0,0, datetime::instanttype ), true,true) {} ~GPatternSolver() { for(std::vector::iterator it= ToDelete.begin(); it != ToDelete.end(); ++it) { (*it)->DeleteIfAllowed(true); } } /* The AddVariable function. Input: the alias of the lifted predicate and a pointer to the its node in the operator tree. Process: adds the variable to the Agenda and resizes the ConstraintGraph. Output: error code */ int AddVariable(std::string alias, Supplier handle); /* The AddConstraint function. Input: the two aliases of the two lifted predicates and a pointer to the "stconstraint" node in the operator tree. Process: adds the constraint to the ConstraintGraph. Output: error code */ int AddConstraint(std::string alias1, std::string alias2, Supplier handle); /* The Solve function. It implements the Solve Pattern algorithm in the paper. */ bool Solve(); /* The MoveNext function. It is used to iterate over the SA list. The function is used by the "start" and "end" operators in the extended STPP. */ bool MoveNext(); /* The GetStart function. It is the impelementation of the "start" operator. */ bool GetStart(std::string alias, Instant& result); /* The GetStart function. It is the impelementation of the "end" operator. */ bool GetEnd(std::string alias, Instant& result); /* The Print function. It is used for debug purposes. */ std::ostream& Print(std::ostream& os); /* The Clear function. It is used to intialize the CSP. It is necessary to call it before processing every tuple in order to reintialize the CSP. */ int Clear(); /* The WriteTuple function writes the current SA entry to a tuple */ void WriteTuple(Tuple* tuple); private: /* The IntervalInstant2IntervalCcReal helper function. It converts the temporalalgebra::Interval to Internal for more efficient processing */ void IntervalInstant2IntervalCcReal( const temporalalgebra::Interval& in, temporalalgebra::Interval& out); /* The Extend function as in the paper. */ bool Extend(int index); /* The IsSupported function. Input: a partial assignment sa and the index of the newly evaluated variable. Process: It checks whether the constraints that involve the new variable are fulfilled. Output: whether the partial assignment is consistent. */ bool IsSupported( std::vector< std::pair, mset::MSet* > >& sa, int index); /* The CheckConstraint helper function. It checks whether an STVector is fulfilled by two lifted predicates. */ bool CheckConstraint(temporalalgebra::Interval& p1, temporalalgebra::Interval& p2, std::vector constraint); /* The PickVariable function. It implements the picking methodology based on the Connectivity rank as in the paper. */ int PickVariable(); }; } // namespace GPattern #endif