BUG-8665: fix memory leak around RangeSets 03/58803/2
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 13 Jun 2017 10:13:58 +0000 (12:13 +0200)
committerTom Pantelis <tompantelis@gmail.com>
Tue, 13 Jun 2017 16:29:19 +0000 (16:29 +0000)
This is a thinko on my part, where I was thinking in terms of a
discrete set (UnsignedLong) and assumed RangeSets will coalesce
individual items.

Unfortunately TreeRangeSet has no way of knowing that that the
domain it operates on is discrete and hence will not merge invididual
ranges.

This patch fixes the problem by using [N,N+1) ranges to address
the problem. A follow-up patch should address this in a more
efficient manner.

Change-Id: Iecc313e09ae0cdd51a42f7d39281f7634f0358a7
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/AbstractFrontendHistory.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/FrontendClientMetadataBuilder.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/FrontendHistoryMetadataBuilder.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/LeaderFrontendState.java

index 8574dc02a6b7179130d7dfd54bfde41be52931e7..1aad9e99823540ab9fd53fe9f8c89a82e67e3054 100644 (file)
@@ -94,7 +94,7 @@ abstract class AbstractFrontendHistory implements Identifiable<LocalHistoryIdent
                         closedTransactions = ImmutableMap.of();
                     }
 
-                    purgedTransactions.add(Range.singleton(ul));
+                    purgedTransactions.add(Range.closedOpen(ul, UnsignedLong.ONE.plus(ul)));
                     LOG.debug("{}: finished purging inherited transaction {}", persistenceId(), id);
                     envelope.sendSuccess(new TransactionPurgeResponse(id, request.getSequence()), readTime() - now);
                 });
@@ -107,12 +107,12 @@ abstract class AbstractFrontendHistory implements Identifiable<LocalHistoryIdent
                 // purged transactions in one go. If it does, we warn about the situation and
                 LOG.warn("{}: transaction {} not tracked in {}, but not present in active transactions", persistenceId,
                     id, purgedTransactions);
-                purgedTransactions.add(Range.singleton(ul));
+                purgedTransactions.add(Range.closedOpen(ul, UnsignedLong.ONE.plus(ul)));
                 return new TransactionPurgeResponse(id, request.getSequence());
             }
 
             tree.purgeTransaction(id, () -> {
-                purgedTransactions.add(Range.singleton(ul));
+                purgedTransactions.add(Range.closedOpen(ul, UnsignedLong.ONE.plus(ul)));
                 transactions.remove(id);
                 LOG.debug("{}: finished purging transaction {}", persistenceId(), id);
                 envelope.sendSuccess(new TransactionPurgeResponse(id, request.getSequence()), readTime() - now);
index e4ab4b5ceff823663de9c6658cc1d98b16032537..519a360b06fd57245cfba8191d791939435ddfa1 100644 (file)
@@ -110,7 +110,8 @@ final class FrontendClientMetadataBuilder implements Builder<FrontendClientMetad
         }
 
         // XXX: do we need to account for cookies?
-        purgedHistories.add(Range.singleton(UnsignedLong.fromLongBits(historyId.getHistoryId())));
+        final UnsignedLong ul = UnsignedLong.fromLongBits(historyId.getHistoryId());
+        purgedHistories.add(Range.closedOpen(ul, UnsignedLong.ONE.plus(ul)));
         LOG.debug("{}: Purged history {}", historyId);
     }
 
index beed765a690590bd8174210861a06c7a2b78f09c..e787edb7a80e391bc2d8bd900535f2b2836b8d10 100644 (file)
@@ -71,7 +71,7 @@ final class FrontendHistoryMetadataBuilder implements Builder<FrontendHistoryMet
     void onTransactionPurged(final TransactionIdentifier txId) {
         final UnsignedLong id = UnsignedLong.fromLongBits(txId.getTransactionId());
         closedTransactions.remove(id);
-        purgedTransactions.add(Range.singleton(id));
+        purgedTransactions.add(Range.closedOpen(id, UnsignedLong.ONE.plus(id)));
     }
 
     /**
index 1ea3c53a5fdb7a5f7a2edcf972948ca5fdb8ef2d..d860bfa289e39f7b9a144aa652a5a030ec4c4546 100644 (file)
@@ -179,7 +179,8 @@ final class LeaderFrontendState implements Identifiable<ClientIdentifier> {
         }
 
         LOG.debug("{}: purging history {}", persistenceId, id);
-        purgedHistories.add(Range.singleton(UnsignedLong.fromLongBits(id.getHistoryId())));
+        final UnsignedLong ul = UnsignedLong.fromLongBits(id.getHistoryId());
+        purgedHistories.add(Range.closedOpen(ul, UnsignedLong.ONE.plus(ul)));
         existing.purge(request.getSequence(), envelope, now);
         return null;
     }