1 8 9 package com.sleepycat.collections; 10 11 import java.io.File ; 12 import java.util.Arrays ; 13 import java.util.Comparator ; 14 15 import junit.framework.Test; 16 import junit.framework.TestCase; 17 import junit.framework.TestSuite; 18 19 import com.sleepycat.bind.ByteArrayBinding; 20 import com.sleepycat.collections.test.DbTestUtil; 21 import com.sleepycat.compat.DbCompat; 22 import com.sleepycat.je.Database; 23 import com.sleepycat.je.DatabaseConfig; 24 import com.sleepycat.je.DatabaseEntry; 25 import com.sleepycat.je.DatabaseException; 26 import com.sleepycat.je.Environment; 27 import com.sleepycat.je.EnvironmentConfig; 28 import com.sleepycat.je.OperationStatus; 29 import com.sleepycat.util.keyrange.KeyRange; 30 import com.sleepycat.util.keyrange.KeyRangeException; 31 32 35 public class KeyRangeTest extends TestCase { 36 37 private static boolean VERBOSE = false; 38 39 private static final byte FF = (byte) 0xFF; 40 41 private static final byte[][] KEYS = { 42 {1}, 43 {FF}, 44 {FF, 0}, 45 {FF, 0x7F}, 46 {FF, FF}, 47 {FF, FF, 0}, 48 {FF, FF, 0x7F}, 49 {FF, FF, FF}, 50 }; 51 private static byte[][] EXTREME_KEY_BYTES = { 52 {0}, 53 {FF, FF, FF, FF}, 54 }; 55 56 private Environment env; 57 private Database store; 58 private DataView view; 59 private DataCursor cursor; 60 61 public static void main(String [] args) 62 throws Exception { 63 64 junit.framework.TestResult tr = 65 junit.textui.TestRunner.run(suite()); 66 if (tr.errorCount() > 0 || 67 tr.failureCount() > 0) { 68 System.exit(1); 69 } else { 70 System.exit(0); 71 } 72 } 73 74 public static Test suite() { 75 76 return new TestSuite(KeyRangeTest.class); 77 } 78 79 public KeyRangeTest(String name) { 80 81 super(name); 82 } 83 84 public void setUp() 85 throws Exception { 86 87 DbTestUtil.printTestName(DbTestUtil.qualifiedTestName(this)); 88 } 89 90 private void openDb(Comparator comparator) 91 throws Exception { 92 93 File dir = DbTestUtil.getNewDir(); 94 ByteArrayBinding dataBinding = new ByteArrayBinding(); 95 EnvironmentConfig envConfig = new EnvironmentConfig(); 96 envConfig.setAllowCreate(true); 97 DbCompat.setInitializeCache(envConfig, true); 98 env = new Environment(dir, envConfig); 99 DatabaseConfig dbConfig = new DatabaseConfig(); 100 DbCompat.setTypeBtree(dbConfig); 101 dbConfig.setAllowCreate(true); 102 if (comparator != null) { 103 DbCompat.setBtreeComparator(dbConfig, comparator); 104 } 105 store = DbCompat.openDatabase(env, null, "test.db", null, dbConfig); 106 view = new DataView(store, dataBinding, dataBinding, null, true, null); 107 } 108 109 private void closeDb() 110 throws Exception { 111 112 store.close(); 113 store = null; 114 env.close(); 115 env = null; 116 } 117 118 public void tearDown() 119 throws Exception { 120 121 try { 122 if (store != null) { 123 store.close(); 124 } 125 } catch (Exception e) { 126 System.out.println("Exception ignored during close: " + e); 127 } 128 try { 129 if (env != null) { 130 env.close(); 131 } 132 } catch (Exception e) { 133 System.out.println("Exception ignored during close: " + e); 134 } 135 136 env = null; 137 store = null; 138 view = null; 139 cursor = null; 140 } 141 142 public void testScan() throws Exception { 143 openDb(null); 144 doScan(false); 145 closeDb(); 146 } 147 148 public void testScanComparator() throws Exception { 149 openDb(new ReverseComparator()); 150 doScan(true); 151 closeDb(); 152 } 153 154 private void doScan(boolean reversed) throws Exception { 155 156 byte[][] keys = new byte[KEYS.length][]; 157 final int end = KEYS.length - 1; 158 cursor = new DataCursor(view, true); 159 for (int i = 0; i <= end; i++) { 160 keys[i] = KEYS[i]; 161 cursor.put(keys[i], KEYS[i], null, false); 162 } 163 cursor.close(); 164 byte[][] extremeKeys = new byte[EXTREME_KEY_BYTES.length][]; 165 for (int i = 0; i < extremeKeys.length; i++) { 166 extremeKeys[i] = EXTREME_KEY_BYTES[i]; 167 } 168 169 171 cursor = new DataCursor(view, false); 172 expectRange(KEYS, 0, end, reversed); 173 cursor.close(); 174 175 177 for (int i = 0; i <= end; i++) { 178 cursor = newCursor(view, keys[i], true, null, false, reversed); 179 expectRange(KEYS, i, end, reversed); 180 cursor.close(); 181 } 182 183 185 for (int i = 0; i <= end; i++) { 186 cursor = newCursor(view, keys[i], false, null, false, reversed); 187 expectRange(KEYS, i + 1, end, reversed); 188 cursor.close(); 189 } 190 191 193 for (int i = 0; i <= end; i++) { 194 cursor = newCursor(view, null, false, keys[i], true, reversed); 195 expectRange(KEYS, 0, i, reversed); 196 cursor.close(); 197 } 198 199 201 for (int i = 0; i <= end; i++) { 202 cursor = newCursor(view, null, false, keys[i], false, reversed); 203 expectRange(KEYS, 0, i - 1, reversed); 204 cursor.close(); 205 } 206 207 209 for (int i = 0; i <= end; i++) { 210 for (int j = i; j <= end; j++) { 211 213 cursor = newCursor(view, keys[i], true, keys[j], 214 true, reversed); 215 expectRange(KEYS, i, j, reversed); 216 cursor.close(); 217 218 220 cursor = newCursor(view, keys[i], true, keys[j], 221 false, reversed); 222 expectRange(KEYS, i, j - 1, reversed); 223 cursor.close(); 224 225 227 cursor = newCursor(view, keys[i], false, keys[j], 228 true, reversed); 229 expectRange(KEYS, i + 1, j, reversed); 230 cursor.close(); 231 232 234 cursor = newCursor(view, keys[i], false, keys[j], 235 false, reversed); 236 expectRange(KEYS, i + 1, j - 1, reversed); 237 cursor.close(); 238 } 239 } 240 241 243 for (int i = 0; i <= end; i++) { 244 cursor = new DataCursor(view, false, keys[i]); 245 expectRange(KEYS, i, i, reversed); 246 cursor.close(); 247 } 248 249 251 cursor = newCursor(view, extremeKeys[0], true, null, false, reversed); 252 expectRange(KEYS, 0, end, reversed); 253 cursor.close(); 254 255 257 cursor = newCursor(view, null, false, extremeKeys[1], true, reversed); 258 expectRange(KEYS, 0, end, reversed); 259 cursor.close(); 260 } 261 262 private DataCursor newCursor(DataView view, 263 Object beginKey, boolean beginInclusive, 264 Object endKey, boolean endInclusive, 265 boolean reversed) 266 throws Exception { 267 268 if (reversed) { 269 return new DataCursor(view, false, 270 endKey, endInclusive, 271 beginKey, beginInclusive); 272 } else { 273 return new DataCursor(view, false, 274 beginKey, beginInclusive, 275 endKey, endInclusive); 276 } 277 } 278 279 private void expectRange(byte[][] bytes, int first, int last, 280 boolean reversed) 281 throws DatabaseException { 282 283 int i; 284 boolean init; 285 for (init = true, i = first;; i++, init = false) { 286 if (checkRange(bytes, first, last, i <= last, 287 reversed, !reversed, init, i)) { 288 break; 289 } 290 } 291 for (init = true, i = last;; i--, init = false) { 292 if (checkRange(bytes, first, last, i >= first, 293 reversed, reversed, init, i)) { 294 break; 295 } 296 } 297 } 298 299 private boolean checkRange(byte[][] bytes, int first, int last, 300 boolean inRange, boolean reversed, 301 boolean forward, boolean init, 302 int i) 303 throws DatabaseException { 304 305 OperationStatus s; 306 if (forward) { 307 if (init) { 308 s = cursor.getFirst(false); 309 } else { 310 s = cursor.getNext(false); 311 } 312 } else { 313 if (init) { 314 s = cursor.getLast(false); 315 } else { 316 s = cursor.getPrev(false); 317 } 318 } 319 320 String msg = " " + (forward ? "next" : "prev") + " i=" + i + 321 " first=" + first + " last=" + last + 322 (reversed ? " reversed" : " not reversed"); 323 324 if (s == OperationStatus.SUCCESS && i == first) { 326 OperationStatus s2 = reversed ? cursor.getNext(false) 327 : cursor.getPrev(false); 328 assertEquals(msg, OperationStatus.NOTFOUND, s2); 329 } 330 if (s == OperationStatus.SUCCESS && i == last) { 331 OperationStatus s2 = reversed ? cursor.getPrev(false) 332 : cursor.getNext(false); 333 assertEquals(msg, OperationStatus.NOTFOUND, s2); 334 } 335 336 byte[] val = (s == OperationStatus.SUCCESS) 337 ? ((byte[]) cursor.getCurrentValue()) 338 : null; 339 340 if (inRange) { 341 assertNotNull("RangeNotFound" + msg, val); 342 343 if (!Arrays.equals(val, bytes[i])){ 344 printBytes(val); 345 printBytes(bytes[i]); 346 fail("RangeKeyNotEqual" + msg); 347 } 348 if (VERBOSE) { 349 System.out.println("GotRange" + msg); 350 } 351 return false; 352 } else { 353 assertEquals("RangeExceeded" + msg, OperationStatus.NOTFOUND, s); 354 return true; 355 } 356 } 357 358 private void printBytes(byte[] bytes) { 359 360 for (int i = 0; i < bytes.length; i += 1) { 361 System.out.print(Integer.toHexString(bytes[i] & 0xFF)); 362 System.out.print(' '); 363 } 364 System.out.println(); 365 } 366 367 public void testSubRanges() { 368 369 DatabaseEntry begin = new DatabaseEntry(); 370 DatabaseEntry begin2 = new DatabaseEntry(); 371 DatabaseEntry end = new DatabaseEntry(); 372 DatabaseEntry end2 = new DatabaseEntry(); 373 KeyRange range = new KeyRange(null); 374 KeyRange range2; 375 376 377 begin.setData(new byte[] { 1 }); 378 end.setData(new byte[] { 2 }); 379 range = range.subRange(begin, true, end, true); 380 381 382 begin2.setData(new byte[] { 0 }); 383 end2.setData(new byte[] { 1 }); 384 try { 385 range2 = range.subRange(begin2, false, end2, true); 386 fail(); 387 } catch (KeyRangeException expected) {} 388 389 390 begin2.setData(new byte[] { 1 }); 391 end2.setData(new byte[] { 3 }); 392 try { 393 range2 = range.subRange(begin2, true, end2, false); 394 fail(); 395 } catch (KeyRangeException expected) {} 396 397 398 begin2.setData(new byte[] { 2 }); 399 end2.setData(new byte[] { 2 }); 400 range2 = range.subRange(begin2, true, end2, true); 401 402 403 begin2.setData(new byte[] { 0 }); 404 end2.setData(new byte[] { 1 }); 405 try { 406 range2 = range.subRange(begin2, true, end2, true); 407 fail(); 408 } catch (KeyRangeException expected) {} 409 410 411 begin2.setData(new byte[] { 0 }); 412 end2.setData(new byte[] { 3 }); 413 try { 414 range2 = range.subRange(begin2, false, end2, true); 415 fail(); 416 } catch (KeyRangeException expected) {} 417 418 419 begin2.setData(new byte[] { 3 }); 420 end2.setData(new byte[] { 3 }); 421 try { 422 range2 = range.subRange(begin2, true, end2, false); 423 fail(); 424 } catch (KeyRangeException expected) {} 425 } 426 427 public static class ReverseComparator implements Comparator { 428 public int compare(Object o1, Object o2) { 429 byte[] d1 = (byte[]) o1; 430 byte[] d2 = (byte[]) o2; 431 int cmp = KeyRange.compareBytes(d1, 0, d1.length, 432 d2, 0, d2.length); 433 if (cmp < 0) { 434 return 1; 435 } else if (cmp > 0) { 436 return -1; 437 } else { 438 return 0; 439 } 440 } 441 } 442 } 443 | Popular Tags |