package peergos.shared.user.fs;
import peergos.shared.cbor.*;
import peergos.shared.user.fs.erasure.Erasure;
import peergos.shared.util.*;
import java.util.*;
import java.util.stream.*;
public class ErasureFragmenter implements Fragmenter {
private final int nOriginalFragments;
private final int nAllowedFailures;
public ErasureFragmenter(int nOriginalFragments, int nAllowedFailures) {
this.nOriginalFragments = nOriginalFragments;
this.nAllowedFailures = nAllowedFailures;
}
@Override
public double storageIncreaseFactor() {
return ((double)(2*nAllowedFailures + nOriginalFragments)) / nOriginalFragments;
}
public byte[][] split(byte[] input) {
return Erasure.split(input, nOriginalFragments, nAllowedFailures);
}
public byte[] recombine(byte[][] encoded, int truncateLength) {
// truncateTo should be input.length
return Erasure.recombine(encoded, truncateLength, nOriginalFragments, nAllowedFailures);
}
@Override
public CborObject toCbor() {
Map<String, CborObject> res = new HashMap<>();
res.put("t", new CborObject.CborLong(Type.ERASURE_CODING.val));
res.put("o", new CborObject.CborLong(nOriginalFragments));
res.put("a", new CborObject.CborLong(nAllowedFailures));
return CborObject.CborMap.build(res);
}
public void serialize(DataSink dout) {
dout.writeInt(Type.ERASURE_CODING.val);
dout.writeInt(nOriginalFragments);
dout.writeInt(nAllowedFailures);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ErasureFragmenter that = (ErasureFragmenter) o;
if (nOriginalFragments != that.nOriginalFragments) return false;
return nAllowedFailures == that.nAllowedFailures;
}
@Override
public int hashCode() {
int result = nOriginalFragments;
result = 31 * result + nAllowedFailures;
return result;
}
public static final Set<Integer> ALLOWED_ORIGINAL = Stream.of(5, 10, 20, 40, 80).collect(Collectors.toSet());
public static final Set<Integer> ALLOWED_FAILURES = Stream.of(5, 10, 20, 40, 80).collect(Collectors.toSet());
public static final int ERASURE_ORIGINAL = 40; // mean 128 KiB fragments, could also use 80, 20, 10, 5
public static final int ERASURE_ALLOWED_FAILURES = 10; // generates twice this extra fragments
}