Committed by
Gerrit Code Review
Implementation of IdBlockStore on top of AtomicCounter
Change-Id: I019322a812262edeca20a55813183a63b4525b75
Showing
11 changed files
with
191 additions
and
22 deletions
| ... | @@ -30,6 +30,29 @@ public interface AsyncAtomicCounter { | ... | @@ -30,6 +30,29 @@ public interface AsyncAtomicCounter { |
| 30 | CompletableFuture<Long> incrementAndGet(); | 30 | CompletableFuture<Long> incrementAndGet(); |
| 31 | 31 | ||
| 32 | /** | 32 | /** |
| 33 | + * Atomically increment by one the current value. | ||
| 34 | + * | ||
| 35 | + * @return previous value | ||
| 36 | + */ | ||
| 37 | + CompletableFuture<Long> getAndIncrement(); | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * Atomically adds the given value to the current value. | ||
| 41 | + * | ||
| 42 | + * @param delta the value to add | ||
| 43 | + * @return previous value | ||
| 44 | + */ | ||
| 45 | + CompletableFuture<Long> getAndAdd(long delta); | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * Atomically adds the given value to the current value. | ||
| 49 | + * | ||
| 50 | + * @param delta the value to add | ||
| 51 | + * @return updated value | ||
| 52 | + */ | ||
| 53 | + CompletableFuture<Long> addAndGet(long delta); | ||
| 54 | + | ||
| 55 | + /** | ||
| 33 | * Returns the current value of the counter without modifying it. | 56 | * Returns the current value of the counter without modifying it. |
| 34 | * | 57 | * |
| 35 | * @return current value | 58 | * @return current value | ... | ... |
| ... | @@ -28,6 +28,29 @@ public interface AtomicCounter { | ... | @@ -28,6 +28,29 @@ public interface AtomicCounter { |
| 28 | long incrementAndGet(); | 28 | long incrementAndGet(); |
| 29 | 29 | ||
| 30 | /** | 30 | /** |
| 31 | + * Atomically increment by one the current value. | ||
| 32 | + * | ||
| 33 | + * @return previous value | ||
| 34 | + */ | ||
| 35 | + long getAndIncrement(); | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Atomically adds the given value to the current value. | ||
| 39 | + * | ||
| 40 | + * @param delta the value to add | ||
| 41 | + * @return previous value | ||
| 42 | + */ | ||
| 43 | + long getAndAdd(long delta); | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * Atomically adds the given value to the current value. | ||
| 47 | + * | ||
| 48 | + * @param delta the value to add | ||
| 49 | + * @return updated value | ||
| 50 | + */ | ||
| 51 | + long addAndGet(long delta); | ||
| 52 | + | ||
| 53 | + /** | ||
| 31 | * Returns the current value of the counter without modifying it. | 54 | * Returns the current value of the counter without modifying it. |
| 32 | * | 55 | * |
| 33 | * @return current value | 56 | * @return current value | ... | ... |
| ... | @@ -190,21 +190,30 @@ public interface DatabaseProxy<K, V> { | ... | @@ -190,21 +190,30 @@ public interface DatabaseProxy<K, V> { |
| 190 | CompletableFuture<Result<Boolean>> replace(String tableName, K key, long oldVersion, V newValue); | 190 | CompletableFuture<Result<Boolean>> replace(String tableName, K key, long oldVersion, V newValue); |
| 191 | 191 | ||
| 192 | /** | 192 | /** |
| 193 | - * Returns the next value for the specified atomic counter after | 193 | + * Atomically add the given value to current value of the specified counter. |
| 194 | - * incrementing the current value by one. | ||
| 195 | * | 194 | * |
| 196 | * @param counterName counter name | 195 | * @param counterName counter name |
| 197 | - * @return next value for the specified counter | 196 | + * @param delta value to add |
| 197 | + * @return updated value | ||
| 198 | */ | 198 | */ |
| 199 | - CompletableFuture<Long> nextValue(String counterName); | 199 | + CompletableFuture<Long> counterAddAndGet(String counterName, long delta); |
| 200 | 200 | ||
| 201 | /** | 201 | /** |
| 202 | - * Returns the current value for the specified atomic counter. | 202 | + * Atomically add the given value to current value of the specified counter. |
| 203 | * | 203 | * |
| 204 | * @param counterName counter name | 204 | * @param counterName counter name |
| 205 | - * @return current value for the specified counter | 205 | + * @param delta value to add |
| 206 | + * @return previous value | ||
| 206 | */ | 207 | */ |
| 207 | - CompletableFuture<Long> currentValue(String counterName); | 208 | + CompletableFuture<Long> counterGetAndAdd(String counterName, long delta); |
| 209 | + | ||
| 210 | + /** | ||
| 211 | + * Returns the current value of the specified atomic counter. | ||
| 212 | + * | ||
| 213 | + * @param counterName counter name | ||
| 214 | + * @return current value | ||
| 215 | + */ | ||
| 216 | + CompletableFuture<Long> counterGet(String counterName); | ||
| 208 | 217 | ||
| 209 | /** | 218 | /** |
| 210 | * Prepare and commit the specified transaction. | 219 | * Prepare and commit the specified transaction. | ... | ... |
| ... | @@ -98,10 +98,16 @@ public interface DatabaseState<K, V> { | ... | @@ -98,10 +98,16 @@ public interface DatabaseState<K, V> { |
| 98 | Result<Boolean> replace(String tableName, K key, long oldVersion, V newValue); | 98 | Result<Boolean> replace(String tableName, K key, long oldVersion, V newValue); |
| 99 | 99 | ||
| 100 | @Command | 100 | @Command |
| 101 | - Long nextValue(String counterName); | 101 | + Long counterIncrementAndGet(String counterName); |
| 102 | + | ||
| 103 | + @Command | ||
| 104 | + Long counterGetAndIncrement(String counterName); | ||
| 105 | + | ||
| 106 | + @Command | ||
| 107 | + Long counterGetAndAdd(String counterName, long delta); | ||
| 102 | 108 | ||
| 103 | @Query | 109 | @Query |
| 104 | - Long currentValue(String counterName); | 110 | + Long counterGet(String counterName); |
| 105 | 111 | ||
| 106 | @Command | 112 | @Command |
| 107 | boolean prepareAndCommit(Transaction transaction); | 113 | boolean prepareAndCommit(Transaction transaction); | ... | ... |
| ... | @@ -16,7 +16,9 @@ | ... | @@ -16,7 +16,9 @@ |
| 16 | package org.onosproject.store.consistent.impl; | 16 | package org.onosproject.store.consistent.impl; |
| 17 | 17 | ||
| 18 | import java.util.concurrent.CompletableFuture; | 18 | import java.util.concurrent.CompletableFuture; |
| 19 | + | ||
| 19 | import org.onosproject.store.service.AsyncAtomicCounter; | 20 | import org.onosproject.store.service.AsyncAtomicCounter; |
| 21 | + | ||
| 20 | import static com.google.common.base.Preconditions.*; | 22 | import static com.google.common.base.Preconditions.*; |
| 21 | 23 | ||
| 22 | /** | 24 | /** |
| ... | @@ -37,11 +39,26 @@ public class DefaultAsyncAtomicCounter implements AsyncAtomicCounter { | ... | @@ -37,11 +39,26 @@ public class DefaultAsyncAtomicCounter implements AsyncAtomicCounter { |
| 37 | 39 | ||
| 38 | @Override | 40 | @Override |
| 39 | public CompletableFuture<Long> incrementAndGet() { | 41 | public CompletableFuture<Long> incrementAndGet() { |
| 40 | - return database.nextValue(name); | 42 | + return addAndGet(1L); |
| 41 | } | 43 | } |
| 42 | 44 | ||
| 43 | @Override | 45 | @Override |
| 44 | public CompletableFuture<Long> get() { | 46 | public CompletableFuture<Long> get() { |
| 45 | - return database.currentValue(name); | 47 | + return database.counterGet(name); |
| 48 | + } | ||
| 49 | + | ||
| 50 | + @Override | ||
| 51 | + public CompletableFuture<Long> getAndIncrement() { | ||
| 52 | + return getAndAdd(1L); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + public CompletableFuture<Long> getAndAdd(long delta) { | ||
| 57 | + return database.counterGetAndAdd(name, delta); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public CompletableFuture<Long> addAndGet(long delta) { | ||
| 62 | + return database.counterAddAndGet(name, delta); | ||
| 46 | } | 63 | } |
| 47 | } | 64 | } | ... | ... |
| ... | @@ -46,6 +46,21 @@ public class DefaultAtomicCounter implements AtomicCounter { | ... | @@ -46,6 +46,21 @@ public class DefaultAtomicCounter implements AtomicCounter { |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | @Override | 48 | @Override |
| 49 | + public long getAndIncrement() { | ||
| 50 | + return complete(asyncCounter.getAndIncrement()); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + @Override | ||
| 54 | + public long getAndAdd(long delta) { | ||
| 55 | + return complete(asyncCounter.getAndAdd(delta)); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + @Override | ||
| 59 | + public long addAndGet(long delta) { | ||
| 60 | + return complete(asyncCounter.getAndAdd(delta)); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + @Override | ||
| 49 | public long get() { | 64 | public long get() { |
| 50 | return complete(asyncCounter.get()); | 65 | return complete(asyncCounter.get()); |
| 51 | } | 66 | } | ... | ... |
| ... | @@ -150,13 +150,18 @@ public class DefaultDatabase extends AbstractResource<Database> implements Datab | ... | @@ -150,13 +150,18 @@ public class DefaultDatabase extends AbstractResource<Database> implements Datab |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | @Override | 152 | @Override |
| 153 | - public CompletableFuture<Long> nextValue(String counterName) { | 153 | + public CompletableFuture<Long> counterGet(String counterName) { |
| 154 | - return checkOpen(() -> proxy.nextValue(counterName)); | 154 | + return checkOpen(() -> proxy.counterGet(counterName)); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | @Override | 157 | @Override |
| 158 | - public CompletableFuture<Long> currentValue(String counterName) { | 158 | + public CompletableFuture<Long> counterAddAndGet(String counterName, long delta) { |
| 159 | - return checkOpen(() -> proxy.currentValue(counterName)); | 159 | + return checkOpen(() -> proxy.counterAddAndGet(counterName, delta)); |
| 160 | + } | ||
| 161 | + | ||
| 162 | + @Override | ||
| 163 | + public CompletableFuture<Long> counterGetAndAdd(String counterName, long delta) { | ||
| 164 | + return checkOpen(() -> proxy.counterGetAndAdd(counterName, delta)); | ||
| 160 | } | 165 | } |
| 161 | 166 | ||
| 162 | @Override | 167 | @Override | ... | ... |
| ... | @@ -225,12 +225,22 @@ public class DefaultDatabaseState implements DatabaseState<String, byte[]> { | ... | @@ -225,12 +225,22 @@ public class DefaultDatabaseState implements DatabaseState<String, byte[]> { |
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | @Override | 227 | @Override |
| 228 | - public Long nextValue(String counterName) { | 228 | + public Long counterIncrementAndGet(String counterName) { |
| 229 | return getCounter(counterName).incrementAndGet(); | 229 | return getCounter(counterName).incrementAndGet(); |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | @Override | 232 | @Override |
| 233 | - public Long currentValue(String counterName) { | 233 | + public Long counterGetAndIncrement(String counterName) { |
| 234 | + return getCounter(counterName).getAndIncrement(); | ||
| 235 | + } | ||
| 236 | + | ||
| 237 | + @Override | ||
| 238 | + public Long counterGetAndAdd(String counterName, long delta) { | ||
| 239 | + return getCounter(counterName).getAndAdd(delta); | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + @Override | ||
| 243 | + public Long counterGet(String counterName) { | ||
| 234 | return getCounter(counterName).get(); | 244 | return getCounter(counterName).get(); |
| 235 | } | 245 | } |
| 236 | 246 | ... | ... |
| ... | @@ -235,15 +235,21 @@ public class PartitionedDatabase implements Database { | ... | @@ -235,15 +235,21 @@ public class PartitionedDatabase implements Database { |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | @Override | 237 | @Override |
| 238 | - public CompletableFuture<Long> nextValue(String counterName) { | 238 | + public CompletableFuture<Long> counterGet(String counterName) { |
| 239 | checkState(isOpen.get(), DB_NOT_OPEN); | 239 | checkState(isOpen.get(), DB_NOT_OPEN); |
| 240 | - return partitioner.getPartition(counterName, counterName).nextValue(counterName); | 240 | + return partitioner.getPartition(counterName, counterName).counterGet(counterName); |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | @Override | 243 | @Override |
| 244 | - public CompletableFuture<Long> currentValue(String counterName) { | 244 | + public CompletableFuture<Long> counterAddAndGet(String counterName, long delta) { |
| 245 | checkState(isOpen.get(), DB_NOT_OPEN); | 245 | checkState(isOpen.get(), DB_NOT_OPEN); |
| 246 | - return partitioner.getPartition(counterName, counterName).currentValue(counterName); | 246 | + return partitioner.getPartition(counterName, counterName).counterAddAndGet(counterName, delta); |
| 247 | + } | ||
| 248 | + | ||
| 249 | + @Override | ||
| 250 | + public CompletableFuture<Long> counterGetAndAdd(String counterName, long delta) { | ||
| 251 | + checkState(isOpen.get(), DB_NOT_OPEN); | ||
| 252 | + return partitioner.getPartition(counterName, counterName).counterGetAndAdd(counterName, delta); | ||
| 247 | } | 253 | } |
| 248 | 254 | ||
| 249 | @Override | 255 | @Override | ... | ... |
core/store/dist/src/main/java/org/onosproject/store/core/impl/ConsistentIdBlockStore.java
0 → 100644
| 1 | +package org.onosproject.store.core.impl; | ||
| 2 | + | ||
| 3 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 4 | + | ||
| 5 | +import java.util.Map; | ||
| 6 | + | ||
| 7 | +import org.apache.felix.scr.annotations.Activate; | ||
| 8 | +import org.apache.felix.scr.annotations.Component; | ||
| 9 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 10 | +import org.apache.felix.scr.annotations.Reference; | ||
| 11 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
| 12 | +import org.apache.felix.scr.annotations.Service; | ||
| 13 | +import org.onosproject.core.IdBlock; | ||
| 14 | +import org.onosproject.core.IdBlockStore; | ||
| 15 | +import org.onosproject.store.service.AtomicCounter; | ||
| 16 | +import org.onosproject.store.service.StorageService; | ||
| 17 | +import org.slf4j.Logger; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.Maps; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * Implementation of {@code IdBlockStore} using {@code AtomicCounter}. | ||
| 23 | + */ | ||
| 24 | +@Component(immediate = true, enabled = true) | ||
| 25 | +@Service | ||
| 26 | +public class ConsistentIdBlockStore implements IdBlockStore { | ||
| 27 | + | ||
| 28 | + private final Logger log = getLogger(getClass()); | ||
| 29 | + private final Map<String, AtomicCounter> topicCounters = Maps.newConcurrentMap(); | ||
| 30 | + | ||
| 31 | + private static final long DEFAULT_BLOCK_SIZE = 0x100000L; | ||
| 32 | + | ||
| 33 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 34 | + protected StorageService storageService; | ||
| 35 | + | ||
| 36 | + @Activate | ||
| 37 | + public void activate() { | ||
| 38 | + log.info("Started"); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + @Deactivate | ||
| 42 | + public void deactivate() { | ||
| 43 | + log.info("Stopped"); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + @Override | ||
| 47 | + public IdBlock getIdBlock(String topic) { | ||
| 48 | + AtomicCounter counter = topicCounters.computeIfAbsent(topic, | ||
| 49 | + name -> storageService.atomicCounterBuilder() | ||
| 50 | + .withName(name) | ||
| 51 | + .build()); | ||
| 52 | + Long blockBase = counter.getAndAdd(DEFAULT_BLOCK_SIZE); | ||
| 53 | + return new IdBlock(blockBase, DEFAULT_BLOCK_SIZE); | ||
| 54 | + } | ||
| 55 | +} |
| ... | @@ -31,7 +31,7 @@ import java.util.Map; | ... | @@ -31,7 +31,7 @@ import java.util.Map; |
| 31 | /** | 31 | /** |
| 32 | * Distributed implementation of id block store using Hazelcast. | 32 | * Distributed implementation of id block store using Hazelcast. |
| 33 | */ | 33 | */ |
| 34 | -@Component(immediate = true) | 34 | +@Component(immediate = false, enabled = false) |
| 35 | @Service | 35 | @Service |
| 36 | public class DistributedIdBlockStore implements IdBlockStore { | 36 | public class DistributedIdBlockStore implements IdBlockStore { |
| 37 | 37 | ... | ... |
-
Please register or login to post a comment