Skip to content

Commit 8a3f587

Browse files
committed
Add fast path to node authorizer for node/edge removal
1 parent 3e0c079 commit 8a3f587

File tree

1 file changed

+35
-21
lines changed

1 file changed

+35
-21
lines changed

plugin/pkg/auth/authorizer/node/graph.go

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ func (g *Graph) deleteVertex_locked(vertexType vertexType, namespace, name strin
175175

176176
// find existing neighbors with a single edge (meaning we are their only neighbor)
177177
neighborsToRemove := []graph.Node{}
178-
neighborsToRecompute := []graph.Node{}
178+
edgesToRemoveFromIndexes := []graph.Edge{}
179179
g.graph.VisitFrom(vertex, func(neighbor graph.Node) bool {
180180
// this downstream neighbor has only one edge (which must be from us), so remove them as well
181181
if g.graph.Degree(neighbor) == 1 {
@@ -188,8 +188,8 @@ func (g *Graph) deleteVertex_locked(vertexType vertexType, namespace, name strin
188188
// this upstream neighbor has only one edge (which must be to us), so remove them as well
189189
neighborsToRemove = append(neighborsToRemove, neighbor)
190190
} else {
191-
// recompute the destination edge index on this neighbor
192-
neighborsToRecompute = append(neighborsToRecompute, neighbor)
191+
// decrement the destination edge index on this neighbor if the edge between us was a destination edge
192+
edgesToRemoveFromIndexes = append(edgesToRemoveFromIndexes, g.graph.EdgeBetween(vertex, neighbor))
193193
}
194194
return true
195195
})
@@ -202,9 +202,9 @@ func (g *Graph) deleteVertex_locked(vertexType vertexType, namespace, name strin
202202
g.removeVertex_locked(neighbor.(*namedVertex))
203203
}
204204

205-
// recompute destination indexes for neighbors that dropped outbound edges
206-
for _, neighbor := range neighborsToRecompute {
207-
g.recomputeDestinationIndex_locked(neighbor)
205+
// remove edges from destination indexes for neighbors that dropped outbound edges
206+
for _, edge := range edgesToRemoveFromIndexes {
207+
g.removeEdgeFromDestinationIndex_locked(edge)
208208
}
209209
}
210210

@@ -220,19 +220,17 @@ func (g *Graph) deleteEdges_locked(fromType, toType vertexType, toNamespace, toN
220220

221221
// delete all edges between vertices of fromType and toVert
222222
neighborsToRemove := []*namedVertex{}
223-
neighborsToRecompute := []*namedVertex{}
223+
edgesToRemove := []graph.Edge{}
224224
g.graph.VisitTo(toVert, func(from graph.Node) bool {
225225
fromVert := from.(*namedVertex)
226226
if fromVert.vertexType != fromType {
227227
return true
228228
}
229-
// remove the edge
230-
g.graph.RemoveEdge(simple.Edge{F: fromVert, T: toVert})
231-
// track vertexes that changed edges
232-
if g.graph.Degree(fromVert) == 0 {
229+
// this neighbor has only one edge (which must be to us), so remove them as well
230+
if g.graph.Degree(fromVert) == 1 {
233231
neighborsToRemove = append(neighborsToRemove, fromVert)
234232
} else {
235-
neighborsToRecompute = append(neighborsToRecompute, fromVert)
233+
edgesToRemove = append(edgesToRemove, g.graph.EdgeBetween(from, toVert))
236234
}
237235
return true
238236
})
@@ -242,9 +240,30 @@ func (g *Graph) deleteEdges_locked(fromType, toType vertexType, toNamespace, toN
242240
g.removeVertex_locked(v)
243241
}
244242

245-
// recompute destination indexes for neighbors that dropped outbound edges
246-
for _, v := range neighborsToRecompute {
247-
g.recomputeDestinationIndex_locked(v)
243+
// remove edges and decrement destination indexes for neighbors that dropped outbound edges
244+
for _, edge := range edgesToRemove {
245+
g.graph.RemoveEdge(edge)
246+
g.removeEdgeFromDestinationIndex_locked(edge)
247+
}
248+
}
249+
250+
// A fastpath for recomputeDestinationIndex_locked for "removing edge" case.
251+
func (g *Graph) removeEdgeFromDestinationIndex_locked(e graph.Edge) {
252+
n := e.From()
253+
// don't maintain indices for nodes with few edges
254+
edgeCount := g.graph.Degree(n)
255+
if edgeCount < g.destinationEdgeThreshold {
256+
delete(g.destinationEdgeIndex, n.ID())
257+
return
258+
}
259+
260+
// decrement the nodeID->destinationID refcount in the index, if the index exists
261+
index := g.destinationEdgeIndex[n.ID()]
262+
if index == nil {
263+
return
264+
}
265+
if destinationEdge, ok := e.(*destinationEdge); ok {
266+
index.decrement(destinationEdge.DestinationID())
248267
}
249268
}
250269

@@ -300,12 +319,7 @@ func (g *Graph) recomputeDestinationIndex_locked(n graph.Node) {
300319
}
301320
return true
302321
})
303-
304-
if len(index.members) < g.destinationEdgeThreshold {
305-
delete(g.destinationEdgeIndex, n.ID())
306-
} else {
307-
g.destinationEdgeIndex[n.ID()] = index
308-
}
322+
g.destinationEdgeIndex[n.ID()] = index
309323
}
310324

311325
// AddPod should only be called once spec.NodeName is populated.

0 commit comments

Comments
 (0)