io.datakernel.crdt.primitives.TPSet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of datakernel-crdt Show documentation
Show all versions of datakernel-crdt Show documentation
Conflict-free replicated data type implementation for DataKernel Framework.
/*
* Copyright (C) 2015-2018 SoftIndex LLC.
*
* Licensed 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 io.datakernel.crdt.primitives;
import io.datakernel.serializer.BinarySerializer;
import io.datakernel.serializer.util.BinaryInput;
import io.datakernel.serializer.util.BinaryOutput;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.stream.Stream;
public final class TPSet implements Set, CrdtMergable> {
private final GSet adds;
private final GSet removes;
private TPSet(GSet adds, GSet removes) {
this.adds = adds;
this.removes = removes;
}
public TPSet() {
this(new GSet<>(), new GSet<>());
}
@SafeVarargs
public static TPSet of(T... items) {
TPSet set = new TPSet<>();
set.addAll(Arrays.asList(items));
return set;
}
@Override
public TPSet merge(TPSet other) {
return new TPSet<>(adds.merge(other.adds), removes.merge(other.removes));
}
@Override
public Stream stream() {
return adds.stream().filter(item -> !removes.contains(item));
}
@Override
public int size() {
//noinspection ReplaceInefficientStreamCount
return (int) stream().count();
}
@Override
public boolean isEmpty() {
return adds.isEmpty() && removes.isEmpty() || removes.containsAll(adds);
}
@Override
public boolean contains(Object o) {
return adds.contains(o) && !removes.contains(o);
}
@Override
public Iterator iterator() {
return stream().iterator();
}
@Override
public Object[] toArray() {
//noinspection SimplifyStreamApiCallChains
return stream().toArray();
}
@SuppressWarnings("SuspiciousToArrayCall")
@Override
public T[] toArray(@NotNull T[] a) {
return stream().toArray($ -> a);
}
@Override
public boolean add(E e) {
return adds.add(e);
}
@Override
@SuppressWarnings("unchecked")
public boolean remove(Object o) {
return removes.add((E) o);
}
@Override
public boolean containsAll(@NotNull Collection> c) {
return adds.containsAll(c) && removes.stream().noneMatch(c::contains);
}
@Override
public boolean addAll(@NotNull Collection extends E> c) {
return adds.addAll(c);
}
@Override
public boolean retainAll(@NotNull Collection> c) {
boolean removed = false;
for (E item : adds) {
if (!c.contains(item)) {
removes.add(item);
removed = true;
}
}
return removed;
}
@Override
@SuppressWarnings("unchecked")
public boolean removeAll(@NotNull Collection> c) {
return removes.addAll((Collection extends E>) c);
}
@Override
public void clear() {
removes.addAll(adds);
}
@Override
public String toString() {
Set set = new HashSet<>();
for (E e : adds) {
if (!removes.contains(e)) {
set.add(e);
}
}
return set.toString();
}
public static class Serializer implements BinarySerializer> {
private final BinarySerializer> gSetSerializer;
public Serializer(BinarySerializer valueSerializer) {
gSetSerializer = new GSet.Serializer<>(valueSerializer);
}
@Override
public void encode(BinaryOutput out, TPSet item) {
gSetSerializer.encode(out, item.adds);
gSetSerializer.encode(out, item.removes);
}
@Override
public TPSet decode(BinaryInput in) {
return new TPSet<>(gSetSerializer.decode(in), gSetSerializer.decode(in));
}
}
}