BUG-8665: fix memory leak around RangeSets
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / FrontendHistoryMetadataBuilder.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.datastore;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.Range;
12 import com.google.common.collect.RangeSet;
13 import com.google.common.collect.TreeRangeSet;
14 import com.google.common.primitives.UnsignedLong;
15 import java.util.HashMap;
16 import java.util.Map;
17 import javax.annotation.Nonnull;
18 import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
19 import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
20 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
21 import org.opendaylight.controller.cluster.datastore.persisted.FrontendHistoryMetadata;
22 import org.opendaylight.yangtools.concepts.Builder;
23 import org.opendaylight.yangtools.concepts.Identifiable;
24
25 final class FrontendHistoryMetadataBuilder implements Builder<FrontendHistoryMetadata>,
26         Identifiable<LocalHistoryIdentifier> {
27
28     private final Map<UnsignedLong, Boolean> closedTransactions;
29     private final RangeSet<UnsignedLong> purgedTransactions;
30     private final LocalHistoryIdentifier identifier;
31
32     private boolean closed;
33
34     FrontendHistoryMetadataBuilder(final LocalHistoryIdentifier identifier) {
35         this.identifier = Preconditions.checkNotNull(identifier);
36         this.purgedTransactions = TreeRangeSet.create();
37         this.closedTransactions = new HashMap<>(2);
38     }
39
40     FrontendHistoryMetadataBuilder(final ClientIdentifier clientId, final FrontendHistoryMetadata meta) {
41         identifier = new LocalHistoryIdentifier(clientId, meta.getHistoryId(), meta.getCookie());
42         closedTransactions = new HashMap<>(meta.getClosedTransactions());
43         purgedTransactions = TreeRangeSet.create(meta.getPurgedTransactions());
44         closed = meta.isClosed();
45     }
46
47     @Override
48     public LocalHistoryIdentifier getIdentifier() {
49         return identifier;
50     }
51
52     @Override
53     public FrontendHistoryMetadata build() {
54         return new FrontendHistoryMetadata(identifier.getHistoryId(), identifier.getCookie(), closed,
55             closedTransactions, purgedTransactions);
56     }
57
58     void onHistoryClosed() {
59         Preconditions.checkState(identifier.getHistoryId() != 0);
60         closed = true;
61     }
62
63     void onTransactionAborted(final TransactionIdentifier txId) {
64         closedTransactions.put(UnsignedLong.fromLongBits(txId.getTransactionId()), Boolean.FALSE);
65     }
66
67     void onTransactionCommitted(final TransactionIdentifier txId) {
68         closedTransactions.put(UnsignedLong.fromLongBits(txId.getTransactionId()), Boolean.TRUE);
69     }
70
71     void onTransactionPurged(final TransactionIdentifier txId) {
72         final UnsignedLong id = UnsignedLong.fromLongBits(txId.getTransactionId());
73         closedTransactions.remove(id);
74         purgedTransactions.add(Range.closedOpen(id, UnsignedLong.ONE.plus(id)));
75     }
76
77     /**
78      * Transform frontend metadata for a particular client history into its {@link LocalFrontendHistory} counterpart.
79      *
80      * @param shard parent shard
81      * @return Leader history state
82      */
83     @Nonnull AbstractFrontendHistory toLeaderState(@Nonnull final Shard shard) {
84         if (identifier.getHistoryId() == 0) {
85             return StandaloneFrontendHistory.recreate(shard.persistenceId(), identifier.getClientId(),
86                 shard.getDataStore(), closedTransactions, purgedTransactions);
87         }
88
89         return LocalFrontendHistory.recreate(shard.persistenceId(), shard.getDataStore(),
90             shard.getDataStore().recreateTransactionChain(identifier, closed), closedTransactions, purgedTransactions);
91     }
92 }

©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.