|
@@ -20,6 +20,7 @@ public class Tree {
|
|
private int aBytes;
|
|
private int aBytes;
|
|
private int tupleBytes;
|
|
private int tupleBytes;
|
|
private long numBuckets;
|
|
private long numBuckets;
|
|
|
|
+ private long numBytes;
|
|
private int d;
|
|
private int d;
|
|
|
|
|
|
private Array64<Bucket> buckets;
|
|
private Array64<Bucket> buckets;
|
|
@@ -37,6 +38,7 @@ public class Tree {
|
|
aBytes = md.getABytesOfTree(treeIndex);
|
|
aBytes = md.getABytesOfTree(treeIndex);
|
|
tupleBytes = md.getTupleBytesOfTree(treeIndex);
|
|
tupleBytes = md.getTupleBytesOfTree(treeIndex);
|
|
numBuckets = md.getNumBucketsOfTree(treeIndex);
|
|
numBuckets = md.getNumBucketsOfTree(treeIndex);
|
|
|
|
+ numBytes = md.getTreeBytesOfTree(treeIndex);
|
|
d = lBits + 1;
|
|
d = lBits + 1;
|
|
|
|
|
|
int fBytes = treeIndex == 0 ? 0 : 1;
|
|
int fBytes = treeIndex == 0 ? 0 : 1;
|
|
@@ -47,6 +49,95 @@ public class Tree {
|
|
buckets.set(i, new Bucket(w, tupleParams, rand));
|
|
buckets.set(i, new Bucket(w, tupleParams, rand));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // only used for xor operation
|
|
|
|
+ // does not deep copy buckets
|
|
|
|
+ private Tree(Tree t) {
|
|
|
|
+ treeIndex = t.getTreeIndex();
|
|
|
|
+ w = t.getW();
|
|
|
|
+ stashSize = t.getStashSize();
|
|
|
|
+ nBits = t.getNBits();
|
|
|
|
+ lBits = t.getLBits();
|
|
|
|
+ alBits = t.getAlBits();
|
|
|
|
+ nBytes = t.getNBytes();
|
|
|
|
+ lBytes = t.getLBytes();
|
|
|
|
+ alBytes = t.getAlBytes();
|
|
|
|
+ aBytes = t.getABytes();
|
|
|
|
+ tupleBytes = t.getTupleBytes();
|
|
|
|
+ numBuckets = t.getNumBuckets();
|
|
|
|
+ numBytes = t.getNumBytes();
|
|
|
|
+ d = t.getD();
|
|
|
|
+
|
|
|
|
+ buckets = new Array64<Bucket>(numBuckets);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // only used for xor operation
|
|
|
|
+ private Array64<Bucket> getBuckets() {
|
|
|
|
+ return buckets;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public Bucket getBucket(long i) {
|
|
|
|
+ return buckets.get(i);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void setBucket(long i, Bucket bucket) {
|
|
|
|
+ if (!buckets.get(i).sameLength(bucket))
|
|
|
|
+ throw new LengthNotMatchException(buckets.get(i).getNumBytes() + " != " + bucket.getNumBytes());
|
|
|
|
+ buckets.set(i, bucket);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public Tree xor(Tree t) {
|
|
|
|
+ if (!this.sameLength(t))
|
|
|
|
+ throw new LengthNotMatchException(numBytes + " != " + t.getNumBytes());
|
|
|
|
+ Tree newTree = new Tree(t);
|
|
|
|
+ for (long i = 0; i < numBuckets; i++)
|
|
|
|
+ // cannot use newTree.setBucket() here
|
|
|
|
+ newTree.getBuckets().set(i, buckets.get(i).xor(t.getBucket(i)));
|
|
|
|
+ return newTree;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void setXor(Tree t) {
|
|
|
|
+ if (!this.sameLength(t))
|
|
|
|
+ throw new LengthNotMatchException(numBytes + " != " + t.getNumBytes());
|
|
|
|
+ for (long i = 0; i < numBuckets; i++)
|
|
|
|
+ buckets.get(i).setXor(t.getBucket(i));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public boolean sameLength(Tree t) {
|
|
|
|
+ return numBytes == t.getNumBytes();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private long[] getBucketIndicesOnPath(long L) {
|
|
|
|
+ if (treeIndex == 0)
|
|
|
|
+ return new long[] { 0 };
|
|
|
|
+ if (L < 0 || L > numBuckets / 2)
|
|
|
|
+ throw new InvalidPathLabelException(BigInteger.valueOf(L).toString(2));
|
|
|
|
+ BigInteger biL = BigInteger.valueOf(L);
|
|
|
|
+ long[] indices = new long[d];
|
|
|
|
+ for (int i = 1; i < d; i++) {
|
|
|
|
+ if (biL.testBit(d - i - 1))
|
|
|
|
+ indices[i] = indices[i - 1] * 2 + 2;
|
|
|
|
+ else
|
|
|
|
+ indices[i] = indices[i - 1] * 2 + 1;
|
|
|
|
+ }
|
|
|
|
+ return indices;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public Bucket[] getBucketsOnPath(long L) {
|
|
|
|
+ long[] indices = getBucketIndicesOnPath(L);
|
|
|
|
+ Bucket[] buckets = new Bucket[indices.length];
|
|
|
|
+ for (int i = 0; i < indices.length; i++)
|
|
|
|
+ buckets[i] = getBucket(indices[i]);
|
|
|
|
+ return buckets;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void setBucketsOnPath(long L, Bucket[] buckets) {
|
|
|
|
+ long[] indices = getBucketIndicesOnPath(L);
|
|
|
|
+ if (indices.length != buckets.length)
|
|
|
|
+ throw new LengthNotMatchException(indices.length + " != " + buckets.length);
|
|
|
|
+ for (int i = 0; i < indices.length; i++)
|
|
|
|
+ setBucket(indices[i], buckets[i]);
|
|
|
|
+ }
|
|
|
|
+
|
|
public int getTreeIndex() {
|
|
public int getTreeIndex() {
|
|
return treeIndex;
|
|
return treeIndex;
|
|
}
|
|
}
|
|
@@ -95,51 +186,11 @@ public class Tree {
|
|
return numBuckets;
|
|
return numBuckets;
|
|
}
|
|
}
|
|
|
|
|
|
- public int getD() {
|
|
|
|
- return d;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Array64<Bucket> getBuckets() {
|
|
|
|
- return buckets;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Bucket getBucket(long bucketIndex) {
|
|
|
|
- return buckets.get(bucketIndex);
|
|
|
|
|
|
+ public long getNumBytes() {
|
|
|
|
+ return numBytes;
|
|
}
|
|
}
|
|
|
|
|
|
- public void setBucket(long bucketIndex, Bucket bucket) {
|
|
|
|
- buckets.set(bucketIndex, bucket);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private long[] getBucketIndicesOnPath(long L) {
|
|
|
|
- if (treeIndex == 0)
|
|
|
|
- return new long[] { 0 };
|
|
|
|
- if (L < 0 || L > numBuckets / 2)
|
|
|
|
- throw new InvalidPathLabelException(BigInteger.valueOf(L).toString(2));
|
|
|
|
- BigInteger biL = BigInteger.valueOf(L);
|
|
|
|
- long[] indices = new long[d];
|
|
|
|
- for (int i = 1; i < d; i++) {
|
|
|
|
- if (biL.testBit(d - i - 1))
|
|
|
|
- indices[i] = indices[i - 1] * 2 + 2;
|
|
|
|
- else
|
|
|
|
- indices[i] = indices[i - 1] * 2 + 1;
|
|
|
|
- }
|
|
|
|
- return indices;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Bucket[] getBucketsOnPath(long L) {
|
|
|
|
- long[] indices = getBucketIndicesOnPath(L);
|
|
|
|
- Bucket[] buckets = new Bucket[indices.length];
|
|
|
|
- for (int i = 0; i < indices.length; i++)
|
|
|
|
- buckets[i] = getBucket(indices[i]);
|
|
|
|
- return buckets;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void setBucketsOnPath(long L, Bucket[] buckets) {
|
|
|
|
- long[] indices = getBucketIndicesOnPath(L);
|
|
|
|
- if (indices.length != buckets.length)
|
|
|
|
- throw new LengthNotMatchException(indices.length + " != " + buckets.length);
|
|
|
|
- for (int i = 0; i < indices.length; i++)
|
|
|
|
- setBucket(indices[i], buckets[i]);
|
|
|
|
|
|
+ public int getD() {
|
|
|
|
+ return d;
|
|
}
|
|
}
|
|
}
|
|
}
|