【发布时间】:2019-04-05 04:19:39
【问题描述】:
我正在使用 java Titan API 来删除两个顶点之间的边,如下所示:
public void deleteEdge(Vertex vFrom, Vertex vTo, String edgeName) {
Iterator<Edge> iter = getEdges(vFrom, Direction.OUT, edgeName);
TitanEdge te = null;
while (iter.hasNext()) {
te = (TitanEdge) iter.next();
TitanVertex tvTo = te.otherVertex(vFrom);
if (vTo == tvTo) {
break;
}
}
if (te != null) { ***----> this is the issue when edge is not present this is set to the last edge present on vFrom and it gets deleted because of this condition. Fixed it to set boolean if edge found and use it with this condition.***
te.remove();
}
}
上面delete方法中使用的getEdges()方法是:
public Iterator<Edge> getEdges(Vertex v, Direction dir, String... labels) {
if (v == null)
return null;
TitanVertex tv = (TitanVertex) v;
Iterator<Edge> iter = (labels == null) ? tv.edges(dir) : tv.edges(dir,
labels);
return iter;
}
我有如下图的顶点和边:
- NodeA ------X----> Node1:TX
Node1:RX -----X----> NodeA
NodeA ------X----> Node2:TX
Node2:RX -----X----> NodeA
NodeA ------X----> Node3:TX
- Node3:RX -----X----> NodeA
由于某些神秘的原因,有时执行 3 到 6 时,我看到 1 被删除了。
这是一种非常奇怪的行为,而且前后矛盾,不会一直发生。
我正在使用由 Titan 图支持的 cassndara。
我不知道 TX 节点是如何丢失边缘的。
TX/RX 节点的唯一区别是 NodeA 是 fromNode 和 TX,toNode 和 RX。
因此,基于我共享的 getEdges 方法,它将检索 NodeA 来自边缘的节点的所有其他边缘,并且仅在 NodeA 是 toNode 时检索特定边缘。
但代码仍将 vTo 与输入 To 节点进行比较,以验证边缘在移除边缘之前是否具有相同的 from 和 To。
这段代码如何从相同的节点中删除边缘但与输入的toNode不同的toNode是一个谜。
我还担心使用 == 比较 toNode 的代码,但到目前为止它工作正常,并且输入边的删除永远不会失败,只是有时它也会删除其他边。
这没有意义,因为当 toNode 与输入匹配时代码会中断,因此它甚至不应该尝试删除任何其他边。
即使由于某些神秘的原因,它成功地将 toNode 与其他一些 toNode 进行比较并删除错误的边,然后不应该删除正确的边,因为它会从循环中中断。
我想知道它是否存在集群问题,但同样的问题发生在没有任何集群的单节点 cassanda 上。
注意事项:
有应用程序代码在同一条边上调用了两次 deleteEdge。 删除边缘后,deleteEdge 方法不提交任何内容。 为用例完成所有工作后,应用程序代码将提交。
一旦我纠正了发送重复删除的应用程序问题,问题似乎就解决了。
所以第一次删除删除了边缘,第二次删除进入并且第一次还没有提交,所以它可以获得相同的边缘并再次删除它。
但是,我很好奇这是如何导致有时在某处删除错误的边缘。
我仍然对使用 == 来比较 toVertex 感到好奇。
它首先使用 getVertex 来获取顶点。
然后它使用 frm.getEdges 来获取具有 toVertex 的边。 不确定边缘上的 toVertex 如何与调用 getVertex 以获取 toVertex 时返回的对象相同。
但我不知道 Titan api 的内部实现,所以正如我所说,它永远不会删除输入边缘。
这个问题让我很好奇,但我无法在任何地方找到任何相关信息或报告的问题。
任何帮助/指针都将非常感激,因为我想知道这是如何发生的。 (我已经修复了应用程序代码不发送重复删除但很好奇重复删除如何导致 Titan api 删除错误的边缘)
我正在使用 Titan api 1.0.0
【问题讨论】:
-
更新:找到根本原因,Titan API 没有问题。如果您注意到它在 while 循环后检查 te != null,则 deleteEdge 的应用程序代码存在问题。当有多个相同标签的边时,第二个重复删除 te 不为空,它是 vFrom 顶点的最后一条边,它被删除。当您尝试删除不存在的边缘时会发生这种情况。我感到非常恼火,以至于我没有更早地意识到这个错误。 :) :) 感谢所有查看问题的人.. 现在一切都好 :) :)
-
很高兴听到您解决了问题!您能否将您的解决方案从评论移至答案和accept it,以便将此问题标记为已关闭?谢谢!