/* ---- This file is part of SECONDO. Copyright (C) 2012, University in Hagen Faculty of Mathematic and 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 ---- */ #include #include "Algebra.h" #include "NestedList.h" #include "ListUtils.h" #include "NList.h" #include "LogMsg.h" #include "QueryProcessor.h" #include "ConstructorTemplates.h" #include "StandardTypes.h" #include "TypeMapUtils.h" #include "Symbols.h" #include "MPointer.h" #include "Mem.h" #include "MemoryObject.h" #include "MemCatalog.h" #include "Utils.h" #include "PropertyGraph2.h" using namespace std; extern NestedList* nl; extern QueryProcessor *qp; namespace pgraph2 { // forward deklatation: part of PropertyGraphAlgebra.cpp void removePGraph2MemoryParts(PGraph2 *pg); //----------------------------------------------------------------------------- PGraph2::~PGraph2() { ClearRelInfos(); } //----------------------------------------------------------------------------- Word PGraph2::Create( const ListExpr typeInfo ) { LOG(30,"PGraph2::Create"); PGraph2* pg=new PGraph2( ); return (SetWord( pg )); } //----------------------------------------------------------------------------- Word PGraph2::In( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { Word result = SetWord(Address(0)); correct = false; NList list(instance); NList typeinfo(typeInfo); LOGOP(30,"PGraph2::In"); LOG(30,"instance",list); LOG(30,"typeinfo",typeinfo); // argument count if ( list.length() != 6 ) { cout << "PGraph2::In - Invalid number of arguments!\n"; return result; } // create PGraph2 PGraph2* pg = new PGraph2(); result.addr = pg; pg->name=list.second().str(); // read node relationnames NList noderels = list.third().second(); for(Cardinal i=0; iAddNodesRel( tableinfo.first().str(), tableinfo.second().str() ); nri->StatCardinality=tableinfo.third().intval(); } // read node relationnames NList edgerels = list.fourth().second(); for(Cardinal i=0; iAddEdgeRel( tableinfo.first().str(), tableinfo.second().first().str(), tableinfo.second().second().str(), tableinfo.second().third().str(), tableinfo.third().first().str(), tableinfo.third().second().str(), tableinfo.third().third().str() ); eri->StatAvgForward =tableinfo.fourth().first().realval(); eri->StatAvgBackward =tableinfo.fourth().second().realval(); eri->StatCardinality =tableinfo.fourth().third().intval(); } // read indexes NList indexes = list.fifth().second(); for(Cardinal i=0; iAddIndex( indexinfo.first().str(), indexinfo.second().str()); } // pg->dumpGraph=false; pg->dumpQueryTree=false; pg->structure=""; NList options = list.sixth().second(); for(Cardinal i=0; istructure=option.second().str(); if (option.first().str()=="dotquery") pg->dumpQueryTree=option.second().intval()==1; if (option.first().str()=="dotgraph") pg->dumpGraph=option.second().intval()==1; } // correct = true; return result; } //----------------------------------------------------------------------------- ListExpr PGraph2::Out( ListExpr typeInfo, Word value ) { PGraph2* pg = static_cast( value.addr ); NList nodetables=NList(); NList edgetables=NList(); NList options=NList(); NList indexes=NList(); for(auto&& item : pg->_nodeRelations) { NList tableinfo= NList( item.second->name ,item.second->idattr, item.second->StatCardinality ); nodetables.append( tableinfo ); } for(auto&& item : pg->_edgeRelations) { NList tableinfo= NList( item.second->EdgeRelName , NList(item.second->FromIdName, item.second->FromRelName, item.second->FromRelKeyName), NList(item.second->ToIdName, item.second->ToRelName, item.second->ToRelKeyName), NList( NList(item.second->StatAvgForward), NList(item.second->StatAvgBackward), NList(item.second->StatCardinality)) ); edgetables.append( tableinfo ); } for(auto&& item : pg->_Indexes) { NList indexinfo= NList( item.second->name ,item.second->attr); indexes.append( indexinfo ); } // options.append( NList("log", to_string(debugLevel))); options.append( NList("structure", pg->structure)); if (pg->dumpQueryTree) options.append(NList(string("dotquery"),string("1"))); if (pg->dumpGraph) options.append( NList(string("dotgraph"),string("1"))); // NList res( NList(0), NList( pg->name ) , NList( NList("nodetables"), nodetables ), NList( NList("edgetables"), edgetables ), NList( NList("indexes"), indexes ), NList( NList("options"), options ) ); LOGOP(30, "PGraph2::Out ", res); return res.listExpr(); } //----------------------------------------------------------------------------- bool PGraph2::Open( SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value ) { LOG(30,"PGraph2::Open"); return DefOpen(PGraph2::In, valueRecord, offset, typeInfo, value); } //----------------------------------------------------------------------------- void PGraph2::Deletion(const ListExpr typeInfo, Word& object ) { PGraph2* pg = static_cast( object.addr ); LOG(30,"PGraph2::Deletion"); removePGraph2MemoryParts(pg); } //----------------------------------------------------------------------------- bool PGraph2::Save( SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { LOG(30,"PGraph2::Save"); ListExpr valueList; string valueString; int valueLength; valueList = Out( nl->First(typeInfo), value ); valueList = nl->OneElemList( valueList ); nl->WriteToString( valueString, valueList ); valueLength = valueString.length(); valueRecord.Write( &valueLength, sizeof( valueLength ), offset ); offset += sizeof( valueLength ); valueRecord.Write( valueString.data(), valueString.length(), offset ); offset += valueString.length(); //cout <<"SAVEDATA: "<Destroy( valueList ); return (true); } //----------------------------------------------------------------------------- EdgeRelInfo *PGraph2::AddEdgeRel(string edgerelname, string fieldfrom, string relfrom,string keyrelfrom, string fieldto, string relto, string keyrelto) { EdgeRelInfo *ei = new EdgeRelInfo(); ei->EdgeRelName = edgerelname; ei->FromIdName = fieldfrom; ei->FromRelName = relfrom; ei->FromRelKeyName = keyrelfrom; ei->ToIdName = fieldto; ei->ToRelName = relto; ei->ToRelKeyName = keyrelto; _edgeRelations[edgerelname] = ei; return ei; } //----------------------------------------------------------------------------- NodeRelInfo* PGraph2::AddNodesRel(string relname, string idattrname) { NodeRelInfo *ni = new NodeRelInfo(); ni->name=relname; ni->idattr=idattrname; _nodeRelations[relname] = ni; return ni; } //----------------------------------------------------------------------------- IndexInfo* PGraph2::AddIndex(std::string relname, std::string attrname) { IndexInfo *ni = new IndexInfo(); ni->name=relname; ni->attr=attrname; _Indexes[relname+"."+attrname] = ni; return ni; } //------------------------------------------------------------------------------ void PGraph2::ClearStat() { for(auto&& r : _nodeRelations) r.second->StatCardinality=-1; for(auto&& r : _edgeRelations) { r.second->StatAvgForward=-1; r.second->StatAvgBackward=-1; } } //------------------------------------------------------------------------------ void PGraph2::ClearRelInfos() { for(auto&& r : _nodeRelations) delete r.second; _nodeRelations.clear(); for(auto&& r : _edgeRelations) delete r.second; _edgeRelations.clear(); } //----------------------------------------------------------------------------- string PGraph2::DumpInfo(MemoryGraphObject *pgm) { string info="PGRAPH Information\n"; info += " - name : "+name + "\n"; info += " - node relations \n"; for(auto && item:_nodeRelations) { info += " - " + item.second->name + " ("+item.second->idattr+")"; if (item.second->StatCardinality>-1) info+= " [Stat:"+to_string(item.second->StatCardinality)+"]"; info += "\n"; } info += " - edge relations \n"; for(auto&& item: _edgeRelations) { info += " - " + item.second->EdgeRelName + " (FROM "+item.second->FromIdName+"=>"+item.second->FromRelName+ "."+item.second->FromRelKeyName+"; "+ "TO "+item.second->ToIdName+"=>"+item.second->ToRelName+ "."+item.second->ToRelKeyName+")"; if (item.second->StatAvgForward>-1 && item.second->StatAvgBackward>-1) info+= "\n [Stat:"+to_string(item.second->StatAvgForward)+ ";"+to_string(item.second->StatAvgBackward)+"]"; info += "\n"; } info += " - indexes \n"; for(auto && item:_Indexes) { info += " - " + item.second->name + "."+ item.second->attr; info += "\n"; } // add information dfomfrom memory object info += "\nConfiguration: \n"; info += " - Loglevel "+to_string(debugLevel)+"\n"; info += " - Structure "+structure+"\n"; info += string(" - dump dot file: querytree:") + (dumpQueryTree ? "yes":"-") + " ; graph:"+(dumpGraph?"yes":"-")+"\n"; // add information dfomfrom memory object info += "\nMemory object information: \n"; if (pgm==NULL || !pgm->IsLoaded()) { info+="!NOT LOADED\n"; } else { info += pgm->DumpInfo()+"\n"; } return info; } //----------------------------------------------------------------------------- pgraphInfo pgri2; pgraphFunctions pgrf2; TypeConstructor pgraph2TC( pgri2, pgrf2 ); //----------------------------------------------------------------------------- };