00001
00002
00003 #ifndef VGS_GraphContainer_H
00004 #define VGS_GraphContainer_H
00005
00006 #include "GraphTypes.h"
00007 #include "GraphData.h"
00008 #include "ByteBuffer.h"
00009 #include "RTree.h"
00010
00011 #include <map>
00012
00013 #if defined(__GNUC__)
00014 #include <ext/hash_set>
00015 #else
00016 #include <hash_set>
00017 #endif
00018
00019 namespace VGServer {
00020
00021 #if defined(__GNUC__)
00022 using __gnu_cxx::hash_set;
00023 #else
00024 using stdext::hash_set;
00025 #endif
00026
00032 class GraphContainer : public GraphData
00033 {
00034 public:
00035
00036 typedef class RTree RTree_t;
00037
00040 struct RTreeData
00041 {
00042
00043 unsigned int src, tgt;
00044
00045 RTreeData()
00046 { }
00047
00048 RTreeData(unsigned int _src, unsigned int _tgt)
00049 : src(_src), tgt(_tgt)
00050 { }
00051
00052 inline bool operator==(const RTreeData &o) const
00053 { return (src == o.src) && (tgt == o.tgt); }
00054 };
00055
00057 struct RTreeDataCallback
00058 {
00059 GraphContainer &gc;
00060
00061 RTreeDataCallback(GraphContainer &_gc)
00062 : gc(_gc)
00063 { }
00064
00065 inline const class RTree_t::Rect getMBR(const RTreeData &d) const
00066 {
00067 int x1 = gc.getVertexAttr(d.src, gc.vertexattrid_xaxis).getInteger();
00068 int y1 = gc.getVertexAttr(d.src, gc.vertexattrid_yaxis).getInteger();
00069
00070 int x2 = gc.getVertexAttr(d.tgt, gc.vertexattrid_xaxis).getInteger();
00071 int y2 = gc.getVertexAttr(d.tgt, gc.vertexattrid_yaxis).getInteger();
00072
00073 return RTree_t::Rect(std::min(x1,x2), std::min(y1,y2),
00074 std::max(x1,x2), std::max(y1,y2));
00075 }
00076 };
00077
00078 typedef RTree_t::Tree<struct RTreeData, struct RTreeDataCallback> GraphRTree;
00079
00080 private:
00081 static const bool rtreemap_descending;
00082
00084 struct rtreemap_compare
00085 {
00086 bool descending;
00087
00088 rtreemap_compare(bool _desc) : descending(_desc) { }
00089
00090 inline bool operator()(unsigned int a, unsigned int b) const {
00091 return descending ? (a > b) : (a < b);
00092 }
00093 };
00094
00096 typedef std::map<unsigned int, GraphRTree, rtreemap_compare> rtreemap_t;
00097 rtreemap_t rtreemap;
00098
00100 void recreateRTree();
00101
00103 RTreeDataCallback rtree_callback;
00104
00106 unsigned int vertexattrid_xaxis, vertexattrid_yaxis;
00107
00108 unsigned int edgeattrid_zaxis;
00109
00112 mutable unsigned int lastqueryedgenum;
00113
00114 public:
00115
00116
00117
00118
00119
00120 unsigned int reinsertnum;
00121 public:
00122 explicit GraphContainer(const class GraphProperties &properties);
00123
00124 ~GraphContainer();
00125
00128 void applyGraphData(class GraphData &newgraph);
00129
00132 void swap(class GraphContainer &other);
00133
00134
00135
00140 void applyChangelist(const class Changelist &cl);
00141
00146 void applyChangeTimeline(const class ChangeTimeline &ct);
00147
00150 void saveSnapshot(std::ostream &s) const;
00151
00154 bool loadSnapshot(std::istream &s);
00155
00156
00157
00158
00160 class VertexRef getVertex(vertexid_t id, const class Changelist &cl) const;
00161
00163 class EdgeRef getEdge(vertexid_t src, vertexid_t tgt, const class Changelist &cl) const;
00164
00166 std::vector<class EdgeRef> getEdgeList(vertexid_t id, const class Changelist &cl) const;
00167
00168
00169
00170
00171 void getGraphProperties(class ByteBuffer &dest) const;
00172
00176 void getArea(coord_t x1, coord_t y1, coord_t x2, coord_t y2, const QueryLimits *ql,
00177 const char* filter, const char* vertexattrsel, const char* edgeattrsel,
00178 const class ChangeTimeline &ct, class ByteBuffer &dest) const;
00179
00181 void getNearestNeighbor(coord_t x1, coord_t y1, coord_t x2, coord_t y2,
00182 coord_t selx, coord_t sely, const QueryLimits *ql,
00183 const char* filter, const char* vertexattrsel, const char* edgeattrsel,
00184 const class Changelist &cl, class ByteBuffer &dest) const;
00185
00188 inline unsigned int getLastQueryEdgenum() const
00189 { return lastqueryedgenum; }
00190
00192 inline unsigned int getRTreeNum() const
00193 { return rtreemap.size(); }
00194
00195 typedef RTree_t::Stats RTreeStats_t;
00196 typedef RTree_t::LevelStats RTreeLevelStats_t;
00197
00199 void getRTreeStats(RTreeStats_t &st) const;
00200
00201 private:
00203 class Visitor
00204 {
00205 private:
00206
00207 const class GraphContainer &gc;
00208 const class AttributeSelectorList &asl_vertex, &asl_edge;
00209 const class FilterRoot &filter;
00210 const class Changelist &cl;
00211
00213 AttributeVertexTinyBlob attrblob;
00214
00216 unsigned int vertexmaxlimit, edgemaxlimit;
00217
00219 int filtertype;
00220
00222 hash_set<unsigned int> &vertexdup;
00223
00224 public:
00226 ByteBuffer vertexout, edgeout;
00227
00229 unsigned int vertexnum, edgenum;
00230
00231 Visitor(const GraphContainer &_gc,
00232 const class AttributeSelectorList &_asl_vertex, const class AttributeSelectorList &_asl_edge,
00233 const class FilterRoot &_filter,
00234 const class Changelist &_cl, unsigned int _vertexmaxlimit, unsigned int _edgemaxlimit,
00235 hash_set<unsigned int> &vertexdup);
00236
00238 bool operator()(const RTree_t::Rect &, const RTreeData &d);
00239
00242 void add_vertex(unsigned int vid);
00243
00246 void add_edge(unsigned int src, unsigned int tgt);
00247 };
00248
00250 class NNResult
00251 {
00252 public:
00254 class RTree_t::Point point;
00255
00257 unsigned int nn_vid;
00258
00260 unsigned int nn_esrc, nn_etgt;
00261
00263 RTree_t::AreaType dist_nn_vid;
00264
00266 RTree_t::AreaType dist_nn_edge;
00267
00269 inline NNResult(const RTree_t::Point &p);
00270
00272 inline void checkVertex(coord_t x, coord_t y, unsigned int vid);
00273
00275 inline void checkEdge(coord_t x1, coord_t y1, coord_t x2, coord_t y2, unsigned int vsrc, unsigned int vtgt);
00276 };
00277
00279 class NNVisitor
00280 {
00281 private:
00282
00283 const class GraphContainer &gc;
00284 const bool use_asl_vertex, use_asl_edge;
00285 const class FilterRoot &filter;
00286 const class Changelist &cl;
00287
00289 unsigned int vertexmaxlimit, edgemaxlimit;
00290
00292 int filtertype;
00293
00295 hash_set<unsigned int> &vertexdup;
00296
00297 public:
00299 unsigned int vertexnum, edgenum;
00300
00302 class NNResult nnr;
00303
00304 NNVisitor(const GraphContainer &_gc, const class NNResult &nnr,
00305 const class AttributeSelectorList &_asl_vertex, const class AttributeSelectorList &_asl_edge,
00306 const class FilterRoot &_filter,
00307 const class Changelist &_cl, unsigned int _vertexmaxlimit, unsigned int _edgemaxlimit,
00308 hash_set<unsigned int> &vertexdup);
00309
00311 bool operator()(const RTree_t::Rect &, const RTreeData &d);
00312
00314 void add_vertex(unsigned int vid);
00315
00317 void add_edge(unsigned int src, unsigned int tgt);
00318 };
00319 };
00320
00324 class VertexRef
00325 {
00326 private:
00328 const class GraphData* graphdata;
00329
00331 unsigned int vertexid;
00332
00335 const AttributeVertexTinyBlob* attrmodified;
00336
00337 protected:
00339 inline VertexRef(const class GraphData* gd, unsigned int vid)
00340 : graphdata(gd), vertexid(vid), attrmodified(NULL)
00341 {
00342 }
00343
00345 inline VertexRef(const class GraphData* gd, unsigned int vid, const AttributeVertexTinyBlob& am)
00346 : graphdata(gd), vertexid(vid), attrmodified(new AttributeVertexTinyBlob(am))
00347 {
00348 }
00349
00351 friend class GraphContainer;
00352
00353 public:
00355 inline VertexRef(const VertexRef &orig)
00356 : graphdata(orig.graphdata), vertexid(orig.vertexid)
00357 {
00358 attrmodified = orig.attrmodified ? new AttributeVertexTinyBlob(*orig.attrmodified) : NULL;
00359 }
00360
00362 inline VertexRef& operator=(const VertexRef &orig)
00363 {
00364 if (attrmodified) delete attrmodified;
00365 graphdata = orig.graphdata;
00366 vertexid = orig.vertexid;
00367 attrmodified = orig.attrmodified ? new AttributeVertexTinyBlob(*orig.attrmodified) : NULL;
00368 return *this;
00369 }
00370
00372 inline ~VertexRef()
00373 {
00374 if (attrmodified) delete attrmodified;
00375 }
00376
00378 inline bool valid() const
00379 { return graphdata != NULL; }
00380
00382 inline vertexid_t getId() const
00383 { return vertexid; }
00384
00386 inline AnyType getAttr(unsigned int attrid) const
00387 {
00388 assert(graphdata);
00389
00390 if (attrmodified)
00391 return attrmodified->getAttrChainValue(0, attrid, graphdata->getProperties().vertexattr);
00392
00393 return graphdata->vertices[vertexid].getAttr(attrid, *graphdata);
00394 }
00395 };
00396
00400 class EdgeRef
00401 {
00402 private:
00404 const class GraphData* graphdata;
00405
00407 vertexid_t srcvid;
00408
00412 unsigned int edgeidx;
00413
00416 const AttributeEdgeTinyBlob* attrmodified;
00417
00418 protected:
00420 inline EdgeRef(const class GraphData* gd, unsigned int _srcvid, unsigned int _edgeidx)
00421 : graphdata(gd), srcvid(_srcvid), edgeidx(_edgeidx), attrmodified(NULL)
00422 {
00423 }
00424
00426 inline EdgeRef(const class GraphData* gd, unsigned int _srcvid, unsigned int _edgeidx, const AttributeEdgeTinyBlob& am)
00427 : graphdata(gd), srcvid(_srcvid), edgeidx(_edgeidx), attrmodified(new AttributeEdgeTinyBlob(am))
00428 {
00429 }
00430
00432 friend class GraphContainer;
00433
00434 public:
00436 inline EdgeRef(const EdgeRef &orig)
00437 : graphdata(orig.graphdata), srcvid(orig.srcvid), edgeidx(orig.edgeidx)
00438 {
00439 attrmodified = orig.attrmodified ? new AttributeEdgeTinyBlob(*orig.attrmodified) : NULL;
00440 }
00441
00443 inline EdgeRef& operator=(const EdgeRef &orig)
00444 {
00445 if (attrmodified) delete attrmodified;
00446 graphdata = orig.graphdata;
00447 srcvid = orig.srcvid;
00448 edgeidx = orig.edgeidx;
00449 attrmodified = orig.attrmodified ? new AttributeEdgeTinyBlob(*orig.attrmodified) : NULL;
00450 return *this;
00451 }
00452
00454 inline ~EdgeRef()
00455 {
00456 if (attrmodified) delete attrmodified;
00457 }
00458
00460 inline bool valid() const
00461 { return graphdata != NULL; }
00462
00464 inline vertexid_t getSource() const
00465 { return srcvid; }
00466
00468 inline vertexid_t getTarget() const
00469 {
00470 if (attrmodified) return edgeidx;
00471 assert(graphdata);
00472 return graphdata->edges[edgeidx].target;
00473 }
00474
00476 inline AnyType getAttr(unsigned int attrid) const
00477 {
00478 assert(graphdata);
00479
00480 if (attrmodified)
00481 return attrmodified->getAttrChainValue(0, attrid, graphdata->getProperties().edgeattr);
00482
00483 return graphdata->edges[edgeidx].getAttr(attrid, *graphdata);
00484 }
00485
00486 };
00487
00488 }
00489
00490 #endif // VGS_GraphContainer_H