MapDBLog: minor fixes
- minimize access to Atomic.Long size - use Iterator to reduce BTree lookup - should not mutate original Map inside stream Change-Id: Ic99ea8769c379e77f1f9478c640d5e5a1bede058
Showing
1 changed file
with
25 additions
and
12 deletions
| ... | @@ -2,13 +2,16 @@ package org.onlab.onos.store.service.impl; | ... | @@ -2,13 +2,16 @@ package org.onlab.onos.store.service.impl; |
| 2 | 2 | ||
| 3 | import static com.google.common.base.Preconditions.checkArgument; | 3 | import static com.google.common.base.Preconditions.checkArgument; |
| 4 | import static com.google.common.base.Preconditions.checkState; | 4 | import static com.google.common.base.Preconditions.checkState; |
| 5 | +import static com.google.common.base.Verify.verifyNotNull; | ||
| 5 | import static org.slf4j.LoggerFactory.getLogger; | 6 | import static org.slf4j.LoggerFactory.getLogger; |
| 6 | 7 | ||
| 7 | import java.io.File; | 8 | import java.io.File; |
| 8 | import java.io.IOException; | 9 | import java.io.IOException; |
| 9 | import java.util.ArrayList; | 10 | import java.util.ArrayList; |
| 10 | import java.util.Arrays; | 11 | import java.util.Arrays; |
| 12 | +import java.util.Iterator; | ||
| 11 | import java.util.List; | 13 | import java.util.List; |
| 14 | +import java.util.Map; | ||
| 12 | import java.util.concurrent.ConcurrentNavigableMap; | 15 | import java.util.concurrent.ConcurrentNavigableMap; |
| 13 | 16 | ||
| 14 | import net.kuujo.copycat.log.Entry; | 17 | import net.kuujo.copycat.log.Entry; |
| ... | @@ -25,8 +28,6 @@ import org.mapdb.TxMaker; | ... | @@ -25,8 +28,6 @@ import org.mapdb.TxMaker; |
| 25 | import org.onlab.onos.store.serializers.StoreSerializer; | 28 | import org.onlab.onos.store.serializers.StoreSerializer; |
| 26 | import org.slf4j.Logger; | 29 | import org.slf4j.Logger; |
| 27 | 30 | ||
| 28 | -import com.google.common.collect.Lists; | ||
| 29 | - | ||
| 30 | /** | 31 | /** |
| 31 | * MapDB based log implementation. | 32 | * MapDB based log implementation. |
| 32 | */ | 33 | */ |
| ... | @@ -84,7 +85,7 @@ public class MapDBLog implements Log { | ... | @@ -84,7 +85,7 @@ public class MapDBLog implements Log { |
| 84 | public List<Long> appendEntries(List<Entry> entries) { | 85 | public List<Long> appendEntries(List<Entry> entries) { |
| 85 | assertIsOpen(); | 86 | assertIsOpen(); |
| 86 | checkArgument(entries != null, "expecting non-null entries"); | 87 | checkArgument(entries != null, "expecting non-null entries"); |
| 87 | - final List<Long> indices = Lists.newArrayList(); | 88 | + final List<Long> indices = new ArrayList<>(entries.size()); |
| 88 | 89 | ||
| 89 | txMaker.execute(new TxBlock() { | 90 | txMaker.execute(new TxBlock() { |
| 90 | @Override | 91 | @Override |
| ... | @@ -92,13 +93,15 @@ public class MapDBLog implements Log { | ... | @@ -92,13 +93,15 @@ public class MapDBLog implements Log { |
| 92 | BTreeMap<Long, byte[]> log = getLogMap(db); | 93 | BTreeMap<Long, byte[]> log = getLogMap(db); |
| 93 | Atomic.Long size = db.getAtomicLong(SIZE_FIELD_NAME); | 94 | Atomic.Long size = db.getAtomicLong(SIZE_FIELD_NAME); |
| 94 | long nextIndex = log.isEmpty() ? 1 : log.lastKey() + 1; | 95 | long nextIndex = log.isEmpty() ? 1 : log.lastKey() + 1; |
| 96 | + long addedBytes = 0; | ||
| 95 | for (Entry entry : entries) { | 97 | for (Entry entry : entries) { |
| 96 | byte[] entryBytes = serializer.encode(entry); | 98 | byte[] entryBytes = serializer.encode(entry); |
| 97 | log.put(nextIndex, entryBytes); | 99 | log.put(nextIndex, entryBytes); |
| 98 | - size.addAndGet(entryBytes.length); | 100 | + addedBytes += entryBytes.length; |
| 99 | indices.add(nextIndex); | 101 | indices.add(nextIndex); |
| 100 | nextIndex++; | 102 | nextIndex++; |
| 101 | } | 103 | } |
| 104 | + size.addAndGet(addedBytes); | ||
| 102 | } | 105 | } |
| 103 | }); | 106 | }); |
| 104 | 107 | ||
| ... | @@ -236,12 +239,15 @@ public class MapDBLog implements Log { | ... | @@ -236,12 +239,15 @@ public class MapDBLog implements Log { |
| 236 | public void tx(DB db) { | 239 | public void tx(DB db) { |
| 237 | BTreeMap<Long, byte[]> log = getLogMap(db); | 240 | BTreeMap<Long, byte[]> log = getLogMap(db); |
| 238 | Atomic.Long size = db.getAtomicLong(SIZE_FIELD_NAME); | 241 | Atomic.Long size = db.getAtomicLong(SIZE_FIELD_NAME); |
| 239 | - long startIndex = index + 1; | 242 | + long removedBytes = 0; |
| 240 | - long endIndex = log.lastKey(); | 243 | + ConcurrentNavigableMap<Long, byte[]> tailMap = log.tailMap(index, false); |
| 241 | - for (long i = startIndex; i <= endIndex; ++i) { | 244 | + Iterator<Map.Entry<Long, byte[]>> it = tailMap.entrySet().iterator(); |
| 242 | - byte[] entryBytes = log.remove(i); | 245 | + while (it.hasNext()) { |
| 243 | - size.addAndGet(-1L * entryBytes.length); | 246 | + Map.Entry<Long, byte[]> entry = it.next(); |
| 247 | + removedBytes += entry.getValue().length; | ||
| 248 | + it.remove(); | ||
| 244 | } | 249 | } |
| 250 | + size.addAndGet(-removedBytes); | ||
| 245 | } | 251 | } |
| 246 | }); | 252 | }); |
| 247 | } | 253 | } |
| ... | @@ -273,9 +279,16 @@ public class MapDBLog implements Log { | ... | @@ -273,9 +279,16 @@ public class MapDBLog implements Log { |
| 273 | BTreeMap<Long, byte[]> log = getLogMap(db); | 279 | BTreeMap<Long, byte[]> log = getLogMap(db); |
| 274 | Atomic.Long size = db.getAtomicLong(SIZE_FIELD_NAME); | 280 | Atomic.Long size = db.getAtomicLong(SIZE_FIELD_NAME); |
| 275 | ConcurrentNavigableMap<Long, byte[]> headMap = log.headMap(index); | 281 | ConcurrentNavigableMap<Long, byte[]> headMap = log.headMap(index); |
| 276 | - long deletedBytes = headMap.keySet().stream().mapToLong(i -> log.remove(i).length).sum(); | 282 | + Iterator<Map.Entry<Long, byte[]>> it = headMap.entrySet().iterator(); |
| 277 | - size.addAndGet(-1 * deletedBytes); | 283 | + |
| 278 | - byte[] entryBytes = serializer.encode(entry); | 284 | + long deletedBytes = 0; |
| 285 | + while (it.hasNext()) { | ||
| 286 | + Map.Entry<Long, byte[]> e = it.next(); | ||
| 287 | + deletedBytes += e.getValue().length; | ||
| 288 | + it.remove(); | ||
| 289 | + } | ||
| 290 | + size.addAndGet(-deletedBytes); | ||
| 291 | + byte[] entryBytes = verifyNotNull(serializer.encode(entry)); | ||
| 279 | byte[] existingEntry = log.put(index, entryBytes); | 292 | byte[] existingEntry = log.put(index, entryBytes); |
| 280 | if (existingEntry != null) { | 293 | if (existingEntry != null) { |
| 281 | size.addAndGet(entryBytes.length - existingEntry.length); | 294 | size.addAndGet(entryBytes.length - existingEntry.length); | ... | ... |
-
Please register or login to post a comment