- final InstanceIdentifier<Node> nii = nodeInstanceId(ni);
-
- final IpPrefix prefix = getPrefix(value);
- final PrefixKey pk = new PrefixKey(prefix);
-
- trans.delete(LogicalDatastoreType.OPERATIONAL, nii.augmentation(Node1.class).child(IgpNodeAttributes.class).child(
- Prefix.class, pk));
-
- removeEmptyNode(trans, nii);
+ if (ni == null) {
+ return;
+ }
+ final NodeUsage present = this.nodes.get(ni);
+ Preconditions.checkState(present != null, "Removing prefix from non-existent node %s", present);
+
+ final PrefixKey pk = new PrefixKey(getPrefix(value));
+ trans.delete(LogicalDatastoreType.OPERATIONAL, present.attrId.child(Prefix.class, pk));
+
+ /*
+ * This is optimization magic: we are reading a list and we want to remove it once it
+ * hits zero. We may be in a transaction, so the read is costly, especially since we
+ * have just modified the list.
+ *
+ * Once we have performed the read, though, we can check the number of nodes, and reuse
+ * it for that number of removals. Note that since we do not track data and thus have
+ * no understanding about the difference between replace and add, we do not ever increase
+ * the life of this in createObject().
+ */
+ present.useCount--;
+ if (present.useCount == 0) {
+ final IgpNodeAttributes attrs = read(trans, present.attrId);
+ if (attrs != null) {
+ present.useCount = attrs.getPrefix().size();
+ if (present.useCount == 0) {
+ trans.delete(LogicalDatastoreType.OPERATIONAL, nodeInstanceId(ni));
+ this.nodes.remove(ni);
+ }
+ }
+ }