blob: f00a5f197dffbfbf923bc99062b0c9d689a26bfc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.gossip.crdt;
import java.util.Map;
import org.apache.gossip.manager.GossipManager;
public class PNCounter implements CrdtCounter<Long, PNCounter> {
private final GrowOnlyCounter pCount;
private final GrowOnlyCounter nCount;
PNCounter(Map<String, Long> pCounters, Map<String, Long> nCounters) {
pCount = new GrowOnlyCounter(pCounters);
nCount = new GrowOnlyCounter(nCounters);
}
public PNCounter(PNCounter starter, Builder builder) {
GrowOnlyCounter.Builder pBuilder = builder.makeGrowOnlyCounterBuilder(builder.pCount());
pCount = new GrowOnlyCounter(starter.pCount, pBuilder);
GrowOnlyCounter.Builder nBuilder = builder.makeGrowOnlyCounterBuilder(builder.nCount());
nCount = new GrowOnlyCounter(starter.nCount, nBuilder);
}
public PNCounter(Builder builder) {
GrowOnlyCounter.Builder pBuilder = builder.makeGrowOnlyCounterBuilder(builder.pCount());
pCount = new GrowOnlyCounter(pBuilder);
GrowOnlyCounter.Builder nBuilder = builder.makeGrowOnlyCounterBuilder(builder.nCount());
nCount = new GrowOnlyCounter(nBuilder);
}
public PNCounter(GossipManager manager) {
pCount = new GrowOnlyCounter(manager);
nCount = new GrowOnlyCounter(manager);
}
public PNCounter(PNCounter starter, PNCounter other) {
pCount = new GrowOnlyCounter(starter.pCount, other.pCount);
nCount = new GrowOnlyCounter(starter.nCount, other.nCount);
}
@Override
public PNCounter merge(PNCounter other) {
return new PNCounter(this, other);
}
@Override
public Long value() {
long pValue = (long) pCount.value();
long nValue = (long) nCount.value();
return pValue - nValue;
}
@Override
public PNCounter optimize() {
return new PNCounter(pCount.getCounters(), nCount.getCounters());
}
@Override
public boolean equals(Object obj) {
if (getClass() != obj.getClass())
return false;
PNCounter other = (PNCounter) obj;
return value().longValue() == other.value().longValue();
}
@Override
public String toString() {
return "PnCounter [pCount=" + pCount + ", nCount=" + nCount + ", value=" + value() + "]";
}
Map<String, Long> getPCounters() {
return pCount.getCounters();
}
Map<String, Long> getNCounters() {
return nCount.getCounters();
}
public static class Builder {
private final GossipManager myManager;
private long value = 0L;
public Builder(GossipManager gossipManager) {
myManager = gossipManager;
}
public long pCount() {
if (value > 0) {
return value;
}
return 0;
}
public long nCount() {
if (value < 0) {
return -value;
}
return 0;
}
public org.apache.gossip.crdt.GrowOnlyCounter.Builder makeGrowOnlyCounterBuilder(long value) {
org.apache.gossip.crdt.GrowOnlyCounter.Builder ret = new org.apache.gossip.crdt.GrowOnlyCounter.Builder(
myManager);
ret.increment(value);
return ret;
}
public PNCounter.Builder increment(long delta) {
value += delta;
return this;
}
public PNCounter.Builder decrement(long delta) {
value -= delta;
return this;
}
}
}