|
@@ -330,89 +330,116 @@ StoreEdge stores a single edge in a partition of the graph. This function will
|
|
|
overwrites any existing edge.
|
|
|
*/
|
|
|
func (gm *Manager) StoreEdge(part string, edge data.Edge) error {
|
|
|
+ trans := newInternalGraphTrans(gm)
|
|
|
+ trans.subtrans = true
|
|
|
|
|
|
-
|
|
|
+ err := gm.gr.graphEvent(trans, EventEdgeStore, part, edge)
|
|
|
|
|
|
- if err := gm.checkEdge(edge); err != nil {
|
|
|
+ if err != nil {
|
|
|
+ if err == ErrEventHandled {
|
|
|
+ err = nil
|
|
|
+ }
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ if err = trans.Commit(); err == nil {
|
|
|
|
|
|
- iht, err := gm.getEdgeIndexHTree(part, edge.Kind(), true)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
- edgeht, err := gm.getEdgeStorageHTree(part, edge.Kind(), true)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
+ if err := gm.checkEdge(edge); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
|
|
|
- end1nodeht, end1ht, err := gm.getNodeStorageHTree(part, edge.End1Kind(), false)
|
|
|
+ iht, err := gm.getEdgeIndexHTree(part, edge.Kind(), true)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- } else if end1ht == nil {
|
|
|
- return &util.GraphError{
|
|
|
- Type: util.ErrInvalidData,
|
|
|
- Detail: "Can't store edge to non-existing node kind: " + edge.End1Kind(),
|
|
|
+ edgeht, err := gm.getEdgeStorageHTree(part, edge.Kind(), true)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
- } else if end1, err := end1nodeht.Get([]byte(PrefixNSAttrs + edge.End1Key())); err != nil || end1 == nil {
|
|
|
- return &util.GraphError{
|
|
|
- Type: util.ErrInvalidData,
|
|
|
- Detail: fmt.Sprintf("Can't find edge endpoint: %s (%s)", edge.End1Key(), edge.End1Kind()),
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ end1nodeht, end1ht, err := gm.getNodeStorageHTree(part, edge.End1Kind(), false)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ } else if end1ht == nil {
|
|
|
+ return &util.GraphError{
|
|
|
+ Type: util.ErrInvalidData,
|
|
|
+ Detail: "Can't store edge to non-existing node kind: " + edge.End1Kind(),
|
|
|
+ }
|
|
|
+ } else if end1, err := end1nodeht.Get([]byte(PrefixNSAttrs + edge.End1Key())); err != nil || end1 == nil {
|
|
|
+ return &util.GraphError{
|
|
|
+ Type: util.ErrInvalidData,
|
|
|
+ Detail: fmt.Sprintf("Can't find edge endpoint: %s (%s)", edge.End1Key(), edge.End1Kind()),
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- end2nodeht, end2ht, err := gm.getNodeStorageHTree(part, edge.End2Kind(), false)
|
|
|
+ end2nodeht, end2ht, err := gm.getNodeStorageHTree(part, edge.End2Kind(), false)
|
|
|
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- } else if end2ht == nil {
|
|
|
- return &util.GraphError{
|
|
|
- Type: util.ErrInvalidData,
|
|
|
- Detail: "Can't store edge to non-existing node kind: " + edge.End2Kind(),
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ } else if end2ht == nil {
|
|
|
+ return &util.GraphError{
|
|
|
+ Type: util.ErrInvalidData,
|
|
|
+ Detail: "Can't store edge to non-existing node kind: " + edge.End2Kind(),
|
|
|
+ }
|
|
|
+ } else if end2, err := end2nodeht.Get([]byte(PrefixNSAttrs + edge.End2Key())); err != nil || end2 == nil {
|
|
|
+ return &util.GraphError{
|
|
|
+ Type: util.ErrInvalidData,
|
|
|
+ Detail: fmt.Sprintf("Can't find edge endpoint: %s (%s)", edge.End2Key(), edge.End2Kind()),
|
|
|
+ }
|
|
|
}
|
|
|
- } else if end2, err := end2nodeht.Get([]byte(PrefixNSAttrs + edge.End2Key())); err != nil || end2 == nil {
|
|
|
- return &util.GraphError{
|
|
|
- Type: util.ErrInvalidData,
|
|
|
- Detail: fmt.Sprintf("Can't find edge endpoint: %s (%s)", edge.End2Key(), edge.End2Kind()),
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ gm.mutex.Lock()
|
|
|
+ defer gm.mutex.Unlock()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ oldedge, err := gm.writeEdge(edge, edgeht, end1ht, end2ht)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- gm.mutex.Lock()
|
|
|
- defer gm.mutex.Unlock()
|
|
|
+ if oldedge == nil {
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
- oldedge, err := gm.writeEdge(edge, edgeht, end1ht, end2ht)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
+ currentCount := gm.EdgeCount(edge.Kind())
|
|
|
+ if err := gm.writeEdgeCount(edge.Kind(), currentCount+1, true); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
|
|
|
- if oldedge == nil {
|
|
|
+ if iht != nil {
|
|
|
|
|
|
-
|
|
|
+ if err := util.NewIndexManager(iht).Index(edge.Key(), edge.IndexMap()); err != nil {
|
|
|
|
|
|
- currentCount := gm.EdgeCount(edge.Kind())
|
|
|
- if err := gm.writeEdgeCount(edge.Kind(), currentCount+1, true); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if iht != nil {
|
|
|
+ } else if iht != nil {
|
|
|
|
|
|
- if err := util.NewIndexManager(iht).Index(edge.Key(), edge.IndexMap()); err != nil {
|
|
|
+ err := util.NewIndexManager(iht).Reindex(edge.Key(), edge.IndexMap(),
|
|
|
+ oldedge.IndexMap())
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
|
|
|
|
|
|
|
|
@@ -421,49 +448,38 @@ func (gm *Manager) StoreEdge(part string, edge data.Edge) error {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- } else if iht != nil {
|
|
|
-
|
|
|
- err := util.NewIndexManager(iht).Reindex(edge.Key(), edge.IndexMap(),
|
|
|
- oldedge.IndexMap())
|
|
|
+
|
|
|
|
|
|
- if err != nil {
|
|
|
+ trans := newInternalGraphTrans(gm)
|
|
|
+ trans.subtrans = true
|
|
|
|
|
|
-
|
|
|
-
|
|
|
+ var event int
|
|
|
+ if oldedge == nil {
|
|
|
+ event = EventEdgeCreated
|
|
|
+ } else {
|
|
|
+ event = EventEdgeUpdated
|
|
|
+ }
|
|
|
|
|
|
+ if err := gm.gr.graphEvent(trans, event, part, edge, oldedge); err != nil && err != ErrEventHandled {
|
|
|
+ return err
|
|
|
+ } else if err := trans.Commit(); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
-
|
|
|
-
|
|
|
- trans := newInternalGraphTrans(gm)
|
|
|
- trans.subtrans = true
|
|
|
-
|
|
|
- var event int
|
|
|
- if oldedge == nil {
|
|
|
- event = EventEdgeCreated
|
|
|
- } else {
|
|
|
- event = EventEdgeUpdated
|
|
|
- }
|
|
|
-
|
|
|
- if err := gm.gr.graphEvent(trans, event, part, edge, oldedge); err != nil {
|
|
|
- return err
|
|
|
- } else if err := trans.Commit(); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
-
|
|
|
+ gm.gs.FlushMain()
|
|
|
|
|
|
- gm.gs.FlushMain()
|
|
|
+ gm.flushEdgeIndex(part, edge.Kind())
|
|
|
|
|
|
- gm.flushEdgeIndex(part, edge.Kind())
|
|
|
+ gm.flushNodeStorage(part, edge.End1Kind())
|
|
|
|
|
|
- gm.flushNodeStorage(part, edge.End1Kind())
|
|
|
+ gm.flushNodeStorage(part, edge.End2Kind())
|
|
|
|
|
|
- gm.flushNodeStorage(part, edge.End2Kind())
|
|
|
+ err = gm.flushEdgeStorage(part, edge.Kind())
|
|
|
+ }
|
|
|
|
|
|
- return gm.flushEdgeStorage(part, edge.Kind())
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
|
|
@@ -604,91 +620,107 @@ func (gm *Manager) writeEdge(edge data.Edge, edgeTree *hash.HTree,
|
|
|
RemoveEdge removes a single edge from a partition of the graph.
|
|
|
*/
|
|
|
func (gm *Manager) RemoveEdge(part string, key string, kind string) (data.Edge, error) {
|
|
|
+ var err error
|
|
|
|
|
|
-
|
|
|
+ trans := newInternalGraphTrans(gm)
|
|
|
+ trans.subtrans = true
|
|
|
|
|
|
- iht, err := gm.getEdgeIndexHTree(part, kind, true)
|
|
|
- if err != nil {
|
|
|
+ if err = gm.gr.graphEvent(trans, EventEdgeDelete, part, key, kind); err != nil {
|
|
|
+ if err == ErrEventHandled {
|
|
|
+ err = nil
|
|
|
+ }
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
- edgeht, err := gm.getEdgeStorageHTree(part, kind, true)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
+ err = trans.Commit()
|
|
|
|
|
|
-
|
|
|
+ if err == nil {
|
|
|
|
|
|
- gm.mutex.Lock()
|
|
|
- defer gm.mutex.Unlock()
|
|
|
+
|
|
|
|
|
|
-
|
|
|
+ iht, err := gm.getEdgeIndexHTree(part, kind, true)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
|
|
|
- node, err := gm.deleteNode(key, kind, edgeht, edgeht)
|
|
|
- edge := data.NewGraphEdgeFromNode(node)
|
|
|
- if err != nil {
|
|
|
- return edge, err
|
|
|
- }
|
|
|
+ edgeht, err := gm.getEdgeStorageHTree(part, kind, true)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
|
|
|
- if node != nil {
|
|
|
+
|
|
|
|
|
|
-
|
|
|
+ gm.mutex.Lock()
|
|
|
+ defer gm.mutex.Unlock()
|
|
|
|
|
|
- _, end1ht, err := gm.getNodeStorageHTree(part, edge.End1Kind(), false)
|
|
|
- if err != nil {
|
|
|
- return edge, err
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
- _, end2ht, err := gm.getNodeStorageHTree(part, edge.End2Kind(), false)
|
|
|
+ node, err := gm.deleteNode(key, kind, edgeht, edgeht)
|
|
|
+ edge := data.NewGraphEdgeFromNode(node)
|
|
|
if err != nil {
|
|
|
return edge, err
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ if node != nil {
|
|
|
|
|
|
- if err := gm.deleteEdge(edge, end1ht, end2ht); err != nil {
|
|
|
- return edge, err
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
- if iht != nil {
|
|
|
- err := util.NewIndexManager(iht).Deindex(key, edge.IndexMap())
|
|
|
+ _, end1ht, err := gm.getNodeStorageHTree(part, edge.End1Kind(), false)
|
|
|
if err != nil {
|
|
|
return edge, err
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
-
|
|
|
+ _, end2ht, err := gm.getNodeStorageHTree(part, edge.End2Kind(), false)
|
|
|
+ if err != nil {
|
|
|
+ return edge, err
|
|
|
+ }
|
|
|
|
|
|
- currentCount := gm.EdgeCount(edge.Kind())
|
|
|
- if err := gm.writeEdgeCount(edge.Kind(), currentCount-1, true); err != nil {
|
|
|
- return edge, err
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
-
|
|
|
+ if err := gm.deleteEdge(edge, end1ht, end2ht); err != nil {
|
|
|
+ return edge, err
|
|
|
+ }
|
|
|
|
|
|
- trans := newInternalGraphTrans(gm)
|
|
|
- trans.subtrans = true
|
|
|
+ if iht != nil {
|
|
|
+ err := util.NewIndexManager(iht).Deindex(key, edge.IndexMap())
|
|
|
+ if err != nil {
|
|
|
+ return edge, err
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if err := gm.gr.graphEvent(trans, EventEdgeDeleted, part, edge); err != nil {
|
|
|
- return edge, err
|
|
|
- } else if err := trans.Commit(); err != nil {
|
|
|
- return edge, err
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
-
|
|
|
+ currentCount := gm.EdgeCount(edge.Kind())
|
|
|
+ if err := gm.writeEdgeCount(edge.Kind(), currentCount-1, true); err != nil {
|
|
|
+ return edge, err
|
|
|
+ }
|
|
|
|
|
|
- gm.gs.FlushMain()
|
|
|
+
|
|
|
|
|
|
- gm.flushEdgeIndex(part, edge.Kind())
|
|
|
+ trans := newInternalGraphTrans(gm)
|
|
|
+ trans.subtrans = true
|
|
|
|
|
|
- gm.flushNodeStorage(part, edge.End1Kind())
|
|
|
+ if err := gm.gr.graphEvent(trans, EventEdgeDeleted, part, edge); err != nil && err != ErrEventHandled {
|
|
|
+ return edge, err
|
|
|
+ } else if err := trans.Commit(); err != nil {
|
|
|
+ return edge, err
|
|
|
+ }
|
|
|
|
|
|
- gm.flushNodeStorage(part, edge.End2Kind())
|
|
|
+
|
|
|
+
|
|
|
+ gm.gs.FlushMain()
|
|
|
+
|
|
|
+ gm.flushEdgeIndex(part, edge.Kind())
|
|
|
|
|
|
- return edge, gm.flushEdgeStorage(part, edge.Kind())
|
|
|
+ gm.flushNodeStorage(part, edge.End1Kind())
|
|
|
+
|
|
|
+ gm.flushNodeStorage(part, edge.End2Kind())
|
|
|
+
|
|
|
+ return edge, gm.flushEdgeStorage(part, edge.Kind())
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- return nil, nil
|
|
|
+ return nil, err
|
|
|
}
|
|
|
|
|
|
|