BUG-8665: fix memory leak around RangeSets
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / FrontendClientMetadataBuilder.java
index ec2cdb6..519a360 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.cluster.datastore;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Verify;
 import com.google.common.collect.Collections2;
@@ -35,8 +36,10 @@ final class FrontendClientMetadataBuilder implements Builder<FrontendClientMetad
     private final Map<LocalHistoryIdentifier, FrontendHistoryMetadataBuilder> currentHistories = new HashMap<>();
     private final RangeSet<UnsignedLong> purgedHistories;
     private final ClientIdentifier identifier;
+    private final String shardName;
 
-    FrontendClientMetadataBuilder(final ClientIdentifier identifier) {
+    FrontendClientMetadataBuilder(final String shardName, final ClientIdentifier identifier) {
+        this.shardName = Preconditions.checkNotNull(shardName);
         this.identifier = Preconditions.checkNotNull(identifier);
         purgedHistories = TreeRangeSet.create();
 
@@ -45,7 +48,8 @@ final class FrontendClientMetadataBuilder implements Builder<FrontendClientMetad
         currentHistories.put(standaloneId, new FrontendHistoryMetadataBuilder(standaloneId));
     }
 
-    FrontendClientMetadataBuilder(final FrontendClientMetadata meta) {
+    FrontendClientMetadataBuilder(final String shardName, final FrontendClientMetadata meta) {
+        this.shardName = Preconditions.checkNotNull(shardName);
         this.identifier = Preconditions.checkNotNull(meta.getIdentifier());
         purgedHistories = TreeRangeSet.create(meta.getPurgedHistories());
 
@@ -57,8 +61,8 @@ final class FrontendClientMetadataBuilder implements Builder<FrontendClientMetad
         // Sanity check and recovery
         final LocalHistoryIdentifier standaloneId = standaloneHistoryId();
         if (!currentHistories.containsKey(standaloneId)) {
-            LOG.warn("Client {} recovered histories {} do not contain stand-alone history, attempting recovery",
-                identifier, currentHistories);
+            LOG.warn("{}: Client {} recovered histories {} do not contain stand-alone history, attempting recovery",
+                shardName, identifier, currentHistories);
             currentHistories.put(standaloneId, new FrontendHistoryMetadataBuilder(standaloneId));
         }
     }
@@ -83,9 +87,9 @@ final class FrontendClientMetadataBuilder implements Builder<FrontendClientMetad
         final FrontendHistoryMetadataBuilder oldMeta = currentHistories.putIfAbsent(historyId, newMeta);
         if (oldMeta != null) {
             // This should not be happening, warn about it
-            LOG.warn("Reused local history {}", historyId);
+            LOG.warn("{}: Reused local history {}", shardName, historyId);
         } else {
-            LOG.debug("Created local history {}", historyId);
+            LOG.debug("{}: Created local history {}", shardName, historyId);
         }
     }
 
@@ -93,30 +97,31 @@ final class FrontendClientMetadataBuilder implements Builder<FrontendClientMetad
         final FrontendHistoryMetadataBuilder builder = currentHistories.get(historyId);
         if (builder != null) {
             builder.onHistoryClosed();
-            LOG.debug("Closed history {}", historyId);
+            LOG.debug("{}: Closed history {}", shardName, historyId);
         } else {
-            LOG.warn("Closed unknown history {}, ignoring", historyId);
+            LOG.warn("{}: Closed unknown history {}, ignoring", shardName, historyId);
         }
     }
 
     void onHistoryPurged(final LocalHistoryIdentifier historyId) {
         final FrontendHistoryMetadataBuilder history = currentHistories.remove(historyId);
         if (history == null) {
-            LOG.warn("Purging unknown history {}", historyId);
+            LOG.warn("{}: Purging unknown history {}", shardName, historyId);
         }
 
         // XXX: do we need to account for cookies?
-        purgedHistories.add(Range.singleton(UnsignedLong.fromLongBits(historyId.getHistoryId())));
-        LOG.debug("Purged history {}", historyId);
+        final UnsignedLong ul = UnsignedLong.fromLongBits(historyId.getHistoryId());
+        purgedHistories.add(Range.closedOpen(ul, UnsignedLong.ONE.plus(ul)));
+        LOG.debug("{}: Purged history {}", historyId);
     }
 
     void onTransactionAborted(final TransactionIdentifier txId) {
         final FrontendHistoryMetadataBuilder history = getHistory(txId);
         if (history != null) {
             history.onTransactionAborted(txId);
-            LOG.debug("Committed transaction {}", txId);
+            LOG.debug("{}: Committed transaction {}", shardName, txId);
         } else {
-            LOG.warn("Unknown history for aborted transaction {}, ignoring", txId);
+            LOG.warn("{}: Unknown history for aborted transaction {}, ignoring", shardName, txId);
         }
     }
 
@@ -124,9 +129,9 @@ final class FrontendClientMetadataBuilder implements Builder<FrontendClientMetad
         final FrontendHistoryMetadataBuilder history = getHistory(txId);
         if (history != null) {
             history.onTransactionCommitted(txId);
-            LOG.debug("Aborted transaction {}", txId);
+            LOG.debug("{}: Aborted transaction {}", shardName, txId);
         } else {
-            LOG.warn("Unknown history for commited transaction {}, ignoring", txId);
+            LOG.warn("{}: Unknown history for commited transaction {}, ignoring", shardName, txId);
         }
     }
 
@@ -134,9 +139,9 @@ final class FrontendClientMetadataBuilder implements Builder<FrontendClientMetad
         final FrontendHistoryMetadataBuilder history = getHistory(txId);
         if (history != null) {
             history.onTransactionPurged(txId);
-            LOG.debug("Purged transaction {}", txId);
+            LOG.debug("{}: Purged transaction {}", shardName, txId);
         } else {
-            LOG.warn("Unknown history for purged transaction {}, ignoring", txId);
+            LOG.warn("{}: Unknown history for purged transaction {}, ignoring", shardName, txId);
         }
     }
 
@@ -175,4 +180,10 @@ final class FrontendClientMetadataBuilder implements Builder<FrontendClientMetad
     private FrontendHistoryMetadataBuilder getHistory(final TransactionIdentifier txId) {
         return currentHistories.get(txId.getHistoryId());
     }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this).add("identifier", identifier).add("current", currentHistories)
+                .add("purged", purgedHistories).toString();
+    }
 }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.