32
32
package org .opensearch .common .cache .tier .keystore ;
33
33
34
34
import org .opensearch .common .Randomness ;
35
- import org .opensearch .common .cache .tier .keystore .RBMIntKeyLookupStore ;
36
- import org .opensearch .common .cache .tier .keystore .RBMSizeEstimator ;
37
35
import org .opensearch .common .metrics .CounterMetric ;
38
36
import org .opensearch .test .OpenSearchTestCase ;
37
+ import org .roaringbitmap .RoaringBitmap ;
39
38
40
39
import java .util .ArrayList ;
41
40
import java .util .HashSet ;
45
44
import java .util .concurrent .ThreadPoolExecutor ;
46
45
47
46
public class RBMIntKeyLookupStoreTests extends OpenSearchTestCase {
47
+
48
+ final int BYTES_IN_MB = 1048576 ;
48
49
public void testInit () {
49
- long memCap = 100 * RBMSizeEstimator . BYTES_IN_MB ;
50
+ long memCap = 100 * BYTES_IN_MB ;
50
51
RBMIntKeyLookupStore kls = new RBMIntKeyLookupStore (memCap );
51
52
assertEquals (0 , kls .getSize ());
52
53
assertEquals (RBMIntKeyLookupStore .KeystoreModuloValue .TWO_TO_TWENTY_EIGHT .getValue (), kls .modulo );
@@ -129,16 +130,35 @@ public void testAddingDuplicates() throws Exception {
129
130
}
130
131
131
132
public void testMemoryCapBlocksAdd () throws Exception {
133
+ // Now that we're using a modified version of rbm.getSizeInBytes(), which doesn't provide an inverse function,
134
+ // we have to test filling just an RBM with random test values first so that we can get the resulting memory cap limit
135
+ // to use with our modified size estimate.
136
+ // This is much noisier so the precision is lower.
137
+
138
+ // It is necessary to use randomly distributed integers for both parts of this test, as we would do with hashes in the cache,
139
+ // as that's what our size estimator is designed for.
140
+ // If we add a run of integers, our size estimator is not valid, especially for small RBMs.
141
+
142
+ int [] maxEntriesArr = new int [] { 1342000 , 100000 , 3000000 };
143
+ long [] rbmReportedSizes = new long [4 ];
144
+ Random rand = Randomness .get ();
145
+ for (int j = 0 ; j < maxEntriesArr .length ; j ++) {
146
+ RoaringBitmap rbm = new RoaringBitmap ();
147
+ for (int i = 0 ; i < maxEntriesArr [j ]; i ++) {
148
+ rbm .add (rand .nextInt ());
149
+ }
150
+ rbmReportedSizes [j ] = rbm .getSizeInBytes ();
151
+ }
132
152
RBMIntKeyLookupStore .KeystoreModuloValue moduloValue = RBMIntKeyLookupStore .KeystoreModuloValue .TWO_TO_TWENTY_NINE ;
133
- for (int maxEntries : new int [] { 2342000 , 1000 , 100000 }) {
134
- long memSizeCapInBytes = RBMSizeEstimator .getSizeInBytesWithModuloValue (maxEntries , moduloValue );
153
+ for (int i = 0 ; i < maxEntriesArr .length ; i ++) {
154
+ double multiplier = RBMIntKeyLookupStore .getRBMSizeMultiplier (maxEntriesArr [i ], moduloValue .getValue ());
155
+ long memSizeCapInBytes = (long ) (rbmReportedSizes [i ] * multiplier );
156
+ //long memSizeCapInBytes = RBMSizeEstimator.getSizeInBytesWithModuloValue(maxEntries, moduloValue);
135
157
RBMIntKeyLookupStore kls = new RBMIntKeyLookupStore (moduloValue , memSizeCapInBytes );
136
- for (int j = 0 ; j < maxEntries + 1000 ; j ++) {
137
- kls .add (j );
158
+ for (int j = 0 ; j < maxEntriesArr [ i ] + 5000 ; j ++) {
159
+ kls .add (rand . nextInt () );
138
160
}
139
- assertTrue (Math .abs (maxEntries - kls .getSize ()) < (double ) maxEntries / 25 );
140
- // exact cap varies a small amount bc of floating point, especially when we use bytes instead of MB for calculations
141
- // precision gets much worse when we compose the two functions, as we do here, but this wouldn't happen in an actual use case
161
+ assertTrue (Math .abs (maxEntriesArr [i ] - kls .getSize ()) < (double ) maxEntriesArr [i ] / 10 );
142
162
}
143
163
}
144
164
@@ -205,7 +225,7 @@ public void testConcurrency() throws Exception {
205
225
}
206
226
207
227
public void testRemoveNoCollisions () throws Exception {
208
- long memCap = 100L * RBMSizeEstimator . BYTES_IN_MB ;
228
+ long memCap = 100L * BYTES_IN_MB ;
209
229
int numToAdd = 195000 ;
210
230
RBMIntKeyLookupStore kls = new RBMIntKeyLookupStore (RBMIntKeyLookupStore .KeystoreModuloValue .NONE , memCap );
211
231
// there should be no collisions for sequential positive numbers up to modulo
@@ -222,7 +242,7 @@ public void testRemoveNoCollisions() throws Exception {
222
242
223
243
public void testRemoveWithCollisions () throws Exception {
224
244
int modulo = (int ) Math .pow (2 , 26 );
225
- long memCap = 100L * RBMSizeEstimator . BYTES_IN_MB ;
245
+ long memCap = 100L * BYTES_IN_MB ;
226
246
RBMIntKeyLookupStore kls = new RBMIntKeyLookupStore (RBMIntKeyLookupStore .KeystoreModuloValue .TWO_TO_TWENTY_SIX , memCap );
227
247
for (int i = 0 ; i < 10 ; i ++) {
228
248
kls .add (i );
@@ -278,24 +298,6 @@ public void testNullInputs() throws Exception {
278
298
assertEquals (4 , kls .getSize ());
279
299
}
280
300
281
- public void testMemoryCapValueInitialization () {
282
- RBMIntKeyLookupStore .KeystoreModuloValue [] mods = RBMIntKeyLookupStore .KeystoreModuloValue .values ();
283
- double [] expectedMultipliers = new double [] { 1.2 , 1.2 , 1 , 1 , 1 };
284
- double [] expectedSlopes = new double [] { 0.637 , 0.637 , 0.619 , 0.614 , 0.629 };
285
- double [] expectedIntercepts = new double [] { 3.091 , 3.091 , 2.993 , 2.905 , 2.603 };
286
- long memSizeCapInBytes = (long ) 100.0 * RBMSizeEstimator .BYTES_IN_MB ;
287
- double delta = 0.01 ;
288
- for (int i = 0 ; i < mods .length ; i ++) {
289
- RBMIntKeyLookupStore .KeystoreModuloValue moduloValue = mods [i ];
290
- RBMIntKeyLookupStore kls = new RBMIntKeyLookupStore (moduloValue , memSizeCapInBytes );
291
- assertEquals (kls .stats .memSizeCapInBytes , kls .getMemorySizeCapInBytes (), 1.0 );
292
- assertEquals (expectedMultipliers [i ], kls .sizeEstimator .bufferMultiplier , delta );
293
- assertEquals (expectedSlopes [i ], kls .sizeEstimator .slope , delta );
294
- assertEquals (expectedIntercepts [i ], kls .sizeEstimator .intercept , delta );
295
- }
296
-
297
- }
298
-
299
301
public void testRemovalLogic () throws Exception {
300
302
RBMIntKeyLookupStore .KeystoreModuloValue moduloValue = RBMIntKeyLookupStore .KeystoreModuloValue .TWO_TO_TWENTY_SIX ;
301
303
int modulo = moduloValue .getValue ();
@@ -395,6 +397,6 @@ public void testRemovalLogicWithHashCollision() throws Exception {
395
397
assertTrue (removalSet .contains (k1 ));
396
398
assertEquals (1 , numCollisions .count ());
397
399
assertTrue (kls .contains (k1 ));
398
- assertTrue (kls .contains (k2 ));
400
+ assertTrue (kls .contains (k2 ));
399
401
}
400
402
}
0 commit comments