Skip to content

Commit 5a76684

Browse files
committed
more value coders and better result of merge register
1 parent 29c6be6 commit 5a76684

5 files changed

Lines changed: 197 additions & 3 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package eu.antidotedb.client;
2+
3+
import java.util.Collections;
4+
import java.util.List;
5+
6+
public class MaxValueMerger<V extends Comparable<V>> implements MergeRegisterKey.ValueMerger<V> {
7+
private V onEmpty;
8+
9+
public MaxValueMerger(V onEmpty) {
10+
this.onEmpty = onEmpty;
11+
}
12+
13+
@Override
14+
public V merge(List<V> concValues) {
15+
if (concValues.isEmpty()) {
16+
return onEmpty;
17+
} else {
18+
return Collections.max(concValues);
19+
}
20+
}
21+
}

src/main/java/eu/antidotedb/client/MergeRegisterKey.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,31 @@
66
import javax.annotation.CheckReturnValue;
77
import java.util.List;
88

9-
public class MergeRegisterKey<V> extends Key<V> {
9+
public class MergeRegisterKey<V> extends Key<MergeRegisterKey.MergeResult<V>> {
10+
public static class MergeResult<V> {
11+
private boolean merged;
12+
private V value;
13+
14+
public MergeResult(boolean merged, V value) {
15+
this.merged = merged;
16+
this.value = value;
17+
}
18+
19+
public boolean isMerged() {
20+
return merged;
21+
}
22+
23+
public V getValue() {
24+
return value;
25+
}
26+
}
27+
1028
public interface ValueMerger<V> {
29+
/**
30+
* Merges the concurrent values of the (possibly empty) list concValues into a single value
31+
* @param concValues the values concurrently written to the register by different replicas
32+
* @return the merged result
33+
*/
1134
V merge(List<V> concValues);
1235
}
1336

@@ -21,8 +44,9 @@ public interface ValueMerger<V> {
2144
}
2245

2346
@Override
24-
V readResponseToValue(AntidotePB.ApbReadObjectResp resp) {
25-
return merger.merge(ResponseDecoder.multiValueRegister(format).readResponseToValue(resp));
47+
MergeResult<V> readResponseToValue(AntidotePB.ApbReadObjectResp resp) {
48+
List<V> concValues = ResponseDecoder.multiValueRegister(format).readResponseToValue(resp);
49+
return new MergeResult<>(concValues.size()>1, merger.merge(concValues));
2650
}
2751

2852
/**
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package eu.antidotedb.client;
2+
3+
import java.util.Collections;
4+
import java.util.List;
5+
6+
public class MinValueMerger<V extends Comparable<V>> implements MergeRegisterKey.ValueMerger<V> {
7+
private V onEmpty;
8+
9+
public MinValueMerger(V onEmpty) {
10+
this.onEmpty = onEmpty;
11+
}
12+
13+
@Override
14+
public V merge(List<V> concValues) {
15+
if (concValues.isEmpty()) {
16+
return onEmpty;
17+
} else {
18+
return Collections.min(concValues);
19+
}
20+
}
21+
}

src/main/java/eu/antidotedb/client/ValueCoder.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.google.protobuf.ByteString;
44

5+
import java.nio.ByteBuffer;
56
import java.util.List;
67
import java.util.function.Function;
78
import java.util.stream.Collectors;
@@ -111,6 +112,78 @@ public List<ByteString> decodeList(List<ByteString> byteStringList) {
111112
}
112113
};
113114

115+
/**
116+
* Stores integers
117+
*/
118+
ValueCoder<Integer> integerCoder = new ValueCoder<Integer>() {
119+
@Override
120+
public ByteString encode(Integer value) {
121+
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
122+
buffer.putInt(value);
123+
buffer.flip();
124+
return ByteString.copyFrom(buffer);
125+
}
126+
127+
@Override
128+
public Integer decode(ByteString bytes) {
129+
return bytes.asReadOnlyByteBuffer().getInt();
130+
}
131+
};
132+
133+
/**
134+
* Stores longs
135+
*/
136+
ValueCoder<Long> longCoder = new ValueCoder<Long>() {
137+
@Override
138+
public ByteString encode(Long value) {
139+
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
140+
buffer.putLong(value);
141+
buffer.flip();
142+
return ByteString.copyFrom(buffer);
143+
}
144+
145+
@Override
146+
public Long decode(ByteString bytes) {
147+
return bytes.asReadOnlyByteBuffer().getLong();
148+
}
149+
};
150+
151+
/**
152+
* Stores floats
153+
*/
154+
ValueCoder<Float> floatCoder = new ValueCoder<Float>() {
155+
@Override
156+
public ByteString encode(Float value) {
157+
ByteBuffer buffer = ByteBuffer.allocate(Float.BYTES);
158+
buffer.putFloat(value);
159+
buffer.flip();
160+
return ByteString.copyFrom(buffer);
161+
}
162+
163+
@Override
164+
public Float decode(ByteString bytes) {
165+
return bytes.asReadOnlyByteBuffer().getFloat();
166+
}
167+
};
168+
169+
/**
170+
* Stores doubles
171+
*/
172+
ValueCoder<Double> doubleCoder = new ValueCoder<Double>() {
173+
@Override
174+
public ByteString encode(Double value) {
175+
ByteBuffer buffer = ByteBuffer.allocate(Double.BYTES);
176+
buffer.putDouble(value);
177+
buffer.flip();
178+
return ByteString.copyFrom(buffer);
179+
}
180+
181+
@Override
182+
public Double decode(ByteString bytes) {
183+
return bytes.asReadOnlyByteBuffer().getDouble();
184+
}
185+
};
186+
114187

115188
/**
116189
* A helper method to create a custom ValueCoder.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package eu.antidotedb.client.test;
2+
3+
import com.google.protobuf.ByteString;
4+
import eu.antidotedb.client.ValueCoder;
5+
import org.junit.Test;
6+
7+
import java.util.Random;
8+
9+
import static org.junit.Assert.assertEquals;
10+
11+
public class SimpleValueCoderTests {
12+
@Test
13+
public void integerCoder() {
14+
Random random = new Random();
15+
for (int i = 0; i<1000; i++) {
16+
int orig = random.nextInt();
17+
ByteString encoded = ValueCoder.integerCoder.encode(orig);
18+
int decoded = ValueCoder.integerCoder.decode(encoded);
19+
assertEquals(orig, decoded);
20+
}
21+
}
22+
23+
@Test
24+
public void longCoder() {
25+
Random random = new Random();
26+
for (int i = 0; i<1000; i++) {
27+
long orig = random.nextLong();
28+
ByteString encoded = ValueCoder.longCoder.encode(orig);
29+
long decoded = ValueCoder.longCoder.decode(encoded);
30+
assertEquals(orig, decoded);
31+
}
32+
}
33+
34+
@Test
35+
public void floatCoder() {
36+
Random random = new Random();
37+
for (int i = 0; i<1000; i++) {
38+
float orig = random.nextFloat();
39+
ByteString encoded = ValueCoder.floatCoder.encode(orig);
40+
float decoded = ValueCoder.floatCoder.decode(encoded);
41+
assertEquals(orig, decoded, 0.0001);
42+
}
43+
}
44+
45+
@Test
46+
public void doubleCoder() {
47+
Random random = new Random();
48+
for (int i = 0; i<1000; i++) {
49+
double orig = random.nextDouble();
50+
ByteString encoded = ValueCoder.doubleCoder.encode(orig);
51+
double decoded = ValueCoder.doubleCoder.decode(encoded);
52+
assertEquals(orig, decoded, 0.0001);
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)