Skip to content

Commit 3c9da0d

Browse files
author
lrhodes
committed
Jon's fix plus my unit test
1 parent 90442a1 commit 3c9da0d

3 files changed

Lines changed: 128 additions & 6 deletions

File tree

src/main/java/com/yahoo/sketches/quantiles/DoublesMergeImpl.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,19 @@ static void mergeInto(final DoublesSketch src, final UpdateDoublesSketch tgt) {
7676
assert srcBitPattern == (srcN / (2L * srcK));
7777

7878
final DoublesSketchAccessor tgtSketchBuf = DoublesSketchAccessor.wrap(tgt, true);
79+
long newTgtBitPattern = tgt.getBitPattern();
7980

8081
for (int srcLvl = 0; srcBitPattern != 0L; srcLvl++, srcBitPattern >>>= 1) {
8182
if ((srcBitPattern & 1L) > 0L) {
82-
final long newTgtBitPattern = DoublesUpdateImpl.inPlacePropagateCarry(
83+
newTgtBitPattern = DoublesUpdateImpl.inPlacePropagateCarry(
8384
srcLvl,
8485
srcSketchBuf.setLevel(srcLvl),
8586
scratch2KAcc,
8687
false,
8788
tgtK,
8889
tgtSketchBuf,
89-
tgt.getBitPattern()
90+
newTgtBitPattern
9091
);
91-
92-
tgt.putBitPattern(newTgtBitPattern);
93-
// won't update tgt.n_ until the very end
9492
}
9593
}
9694

@@ -100,6 +98,7 @@ static void mergeInto(final DoublesSketch src, final UpdateDoublesSketch tgt) {
10098
}
10199

102100
tgt.putN(nFinal);
101+
tgt.putBitPattern(newTgtBitPattern); // no-op if direct
103102

104103
assert (tgt.getN() / (2L * tgtK)) == tgt.getBitPattern(); // internal consistency check
105104

src/main/java/com/yahoo/sketches/quantiles/DoublesSketch.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ public abstract class DoublesSketch {
138138
* received in exactly the same order. This is only useful when performing test comparisons,
139139
* otherwise is not recommended.
140140
*/
141-
public static final Random rand = new Random();
141+
public static Random rand = new Random();
142142

143143
DoublesSketch(final int k) {
144144
Util.checkK(k);
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright 2019, Yahoo! Inc. Licensed under the terms of the
3+
* Apache License 2.0. See LICENSE file at the project root for terms.
4+
*/
5+
6+
package com.yahoo.sketches.quantiles;
7+
8+
import static com.yahoo.sketches.quantiles.Util.LS;
9+
import static org.testng.Assert.assertEquals;
10+
import static org.testng.Assert.assertTrue;
11+
12+
import java.util.HashSet;
13+
import java.util.Random;
14+
15+
import org.testng.annotations.Test;
16+
17+
import com.yahoo.memory.WritableDirectHandle;
18+
import com.yahoo.memory.WritableMemory;
19+
20+
/**
21+
* @author Lee Rhodes
22+
*/
23+
public class DebugUnionTest {
24+
25+
@Test
26+
public void test() {
27+
final int n = 70_000;
28+
final int valueLimit = 1000;
29+
final int numSketches = 3;
30+
final int sketchK = 8;
31+
final int unionK = 8;
32+
UpdateDoublesSketch[] sketchArr = new UpdateDoublesSketch[numSketches];
33+
34+
//builds the input sketches, all on heap
35+
DoublesSketch.rand = new Random(1); //make deterministic for test
36+
final HashSet<Double> set = new HashSet<>(); //holds input values
37+
for (int s = 0; s < numSketches; s++) {
38+
sketchArr[s] = buildHeapSketch(sketchK, n, valueLimit, set);
39+
}
40+
41+
//loads the on heap union
42+
DoublesSketch.rand = new Random(1); //make deterministic for test
43+
DoublesUnion hUnion = DoublesUnion.builder().setMaxK(unionK).build();
44+
for (int s = 0; s < numSketches; s++) { hUnion.update(sketchArr[s]); }
45+
DoublesSketch hSketch = hUnion.getResult();
46+
47+
//loads the direct union
48+
DoublesSketch.rand = new Random(1); //make deterministic for test
49+
DoublesUnion dUnion;
50+
DoublesSketch dSketch;
51+
try ( WritableDirectHandle wdh = WritableMemory.allocateDirect(10_000_000) ) {
52+
WritableMemory wmem = wdh.get();
53+
dUnion = DoublesUnion.builder().setMaxK(8).build(wmem);
54+
for (int s = 0; s < numSketches; s++) { dUnion.update(sketchArr[s]); }
55+
dSketch = dUnion.getResult(); //result is on heap
56+
}
57+
58+
//iterates and counts errors
59+
int hCount = hSketch.getRetainedItems();
60+
int dCount = dSketch.getRetainedItems();
61+
62+
assertEquals(hCount, dCount); //Retained items must be the same
63+
64+
double[] heapItems = new double[hCount];
65+
double[] directItems = new double[dCount];
66+
int hErrors = 0;
67+
int dErrors = 0;
68+
69+
DoublesSketchIterator hit = hSketch.iterator();
70+
DoublesSketchIterator dit = dSketch.iterator();
71+
int i = 0;
72+
while (hit.next() && dit.next()) {
73+
double v = hit.getValue();
74+
heapItems[i] = v;
75+
if (!set.contains(v)) { hErrors++; }
76+
77+
double w = dit.getValue();
78+
directItems[i] = w;
79+
if (!set.contains(w)) { dErrors++; }
80+
i++;
81+
assertEquals(v, w, 0); //Items must be returned in same order and be equal
82+
}
83+
assertTrue(hErrors == 0);
84+
assertTrue(dErrors == 0);
85+
86+
//println("HeapUnion : Values: " + hCount + ", errors: " + hErrors);
87+
//println(hSketch.toString(true, true));
88+
89+
//println("DirectUnion: Values: " + dCount + ", errors: " + dErrors);
90+
//println(dSketch.toString(true, true));
91+
}
92+
93+
private static UpdateDoublesSketch buildHeapSketch(final int k, final int n, final int valueLimit,
94+
final HashSet<Double> set) {
95+
final UpdateDoublesSketch uSk = DoublesSketch.builder().setK(k).build();
96+
for (int i = 0; i < n; i++) {
97+
final double value = DoublesSketch.rand.nextInt(valueLimit) + 1;
98+
uSk.update(value);
99+
set.add(value);
100+
}
101+
return uSk;
102+
}
103+
104+
@Test
105+
public void printlnTest() {
106+
println("PRINTING: " + this.getClass().getName());
107+
}
108+
109+
/**
110+
* @param s value to print
111+
*/
112+
static void println(String s) {
113+
print(s+LS);
114+
}
115+
116+
/**
117+
* @param s value to print
118+
*/
119+
static void print(String s) {
120+
//System.out.print(s); //disable here
121+
}
122+
123+
}

0 commit comments

Comments
 (0)