Improve Frontend{Client,History}Metadata
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / persisted / FrontendHistoryMetadata.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.persisted;
9
10 import com.google.common.base.MoreObjects;
11 import com.google.common.base.Verify;
12 import com.google.common.collect.ImmutableMap;
13 import com.google.common.collect.ImmutableRangeSet;
14 import com.google.common.collect.Range;
15 import com.google.common.collect.RangeSet;
16 import com.google.common.collect.TreeRangeSet;
17 import com.google.common.primitives.UnsignedLong;
18 import java.io.DataInput;
19 import java.io.DataOutput;
20 import java.io.IOException;
21 import java.util.HashMap;
22 import java.util.Map;
23 import java.util.Map.Entry;
24 import java.util.Set;
25 import org.eclipse.jdt.annotation.NonNull;
26 import org.opendaylight.yangtools.concepts.WritableObject;
27 import org.opendaylight.yangtools.concepts.WritableObjects;
28
29 public final class FrontendHistoryMetadata implements WritableObject {
30     private final @NonNull ImmutableRangeSet<UnsignedLong> purgedTransactions;
31     private final @NonNull ImmutableMap<UnsignedLong, Boolean> closedTransactions;
32     private final long historyId;
33     private final long cookie;
34     private final boolean closed;
35
36     public FrontendHistoryMetadata(final long historyId, final long cookie, final boolean closed,
37             final Map<UnsignedLong, Boolean> closedTransactions, final RangeSet<UnsignedLong> purgedTransactions) {
38         this.historyId = historyId;
39         this.cookie = cookie;
40         this.closed = closed;
41         this.closedTransactions = ImmutableMap.copyOf(closedTransactions);
42         this.purgedTransactions = ImmutableRangeSet.copyOf(purgedTransactions);
43     }
44
45     public long getHistoryId() {
46         return historyId;
47     }
48
49     public long getCookie() {
50         return cookie;
51     }
52
53     public boolean isClosed() {
54         return closed;
55     }
56
57     public Map<UnsignedLong, Boolean> getClosedTransactions() {
58         return closedTransactions;
59     }
60
61     public RangeSet<UnsignedLong> getPurgedTransactions() {
62         return purgedTransactions;
63     }
64
65     @Override
66     public void writeTo(final DataOutput out) throws IOException {
67         WritableObjects.writeLongs(out, historyId, cookie);
68         out.writeBoolean(closed);
69
70         final Set<Range<UnsignedLong>> purgedRanges = purgedTransactions.asRanges();
71         WritableObjects.writeLongs(out, closedTransactions.size(), purgedRanges.size());
72         for (Entry<UnsignedLong, Boolean> e : closedTransactions.entrySet()) {
73             WritableObjects.writeLong(out, e.getKey().longValue());
74             out.writeBoolean(e.getValue());
75         }
76         for (Range<UnsignedLong> r : purgedRanges) {
77             WritableObjects.writeLongs(out, r.lowerEndpoint().longValue(), r.upperEndpoint().longValue());
78         }
79     }
80
81     public static FrontendHistoryMetadata readFrom(final DataInput in) throws IOException {
82         byte header = WritableObjects.readLongHeader(in);
83         final long historyId = WritableObjects.readFirstLong(in, header);
84         final long cookie = WritableObjects.readSecondLong(in, header);
85         final boolean closed = in.readBoolean();
86
87         header = WritableObjects.readLongHeader(in);
88         long ls = WritableObjects.readFirstLong(in, header);
89         Verify.verify(ls >= 0 && ls <= Integer.MAX_VALUE);
90         final int csize = (int) ls;
91
92         ls = WritableObjects.readSecondLong(in, header);
93         Verify.verify(ls >= 0 && ls <= Integer.MAX_VALUE);
94         final int psize = (int) ls;
95
96         final Map<UnsignedLong, Boolean> closedTransactions = new HashMap<>(csize);
97         for (int i = 0; i < csize; ++i) {
98             final UnsignedLong key = UnsignedLong.fromLongBits(WritableObjects.readLong(in));
99             final Boolean value = in.readBoolean();
100             closedTransactions.put(key, value);
101         }
102         final RangeSet<UnsignedLong> purgedTransactions = TreeRangeSet.create();
103         for (int i = 0; i < psize; ++i) {
104             final byte h = WritableObjects.readLongHeader(in);
105             final UnsignedLong l = UnsignedLong.fromLongBits(WritableObjects.readFirstLong(in, h));
106             final UnsignedLong u = UnsignedLong.fromLongBits(WritableObjects.readSecondLong(in, h));
107             purgedTransactions.add(Range.closedOpen(l, u));
108         }
109
110         return new FrontendHistoryMetadata(historyId, cookie, closed, closedTransactions, purgedTransactions);
111     }
112
113     @Override
114     public String toString() {
115         return MoreObjects.toStringHelper(FrontendHistoryMetadata.class).add("historyId", historyId)
116                 .add("cookie", cookie).add("closed", closed).add("closedTransactions", closedTransactions)
117                 .add("purgedTransactions", purgedTransactions).toString();
118     }
119 }