1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 2 // This source code is licensed under both the GPLv2 (found in the 3 // COPYING file in the root directory) and Apache 2.0 License 4 // (found in the LICENSE.Apache file in the root directory). 5 6 package org.rocksdb; 7 8 /** 9 * The class that controls the get behavior. 10 * 11 * Note that dispose() must be called before an Options instance 12 * become out-of-scope to release the allocated memory in c++. 13 */ 14 public class ReadOptions extends RocksObject { ReadOptions()15 public ReadOptions() { 16 super(newReadOptions()); 17 } 18 19 /** 20 * @param verifyChecksums verification will be performed on every read 21 * when set to true 22 * @param fillCache if true, then fill-cache behavior will be performed. 23 */ ReadOptions(final boolean verifyChecksums, final boolean fillCache)24 public ReadOptions(final boolean verifyChecksums, final boolean fillCache) { 25 super(newReadOptions(verifyChecksums, fillCache)); 26 } 27 28 /** 29 * Copy constructor. 30 * 31 * NOTE: This does a shallow copy, which means snapshot, iterate_upper_bound 32 * and other pointers will be cloned! 33 * 34 * @param other The ReadOptions to copy. 35 */ ReadOptions(ReadOptions other)36 public ReadOptions(ReadOptions other) { 37 super(copyReadOptions(other.nativeHandle_)); 38 this.iterateLowerBoundSlice_ = other.iterateLowerBoundSlice_; 39 this.iterateUpperBoundSlice_ = other.iterateUpperBoundSlice_; 40 } 41 42 /** 43 * If true, all data read from underlying storage will be 44 * verified against corresponding checksums. 45 * Default: true 46 * 47 * @return true if checksum verification is on. 48 */ verifyChecksums()49 public boolean verifyChecksums() { 50 assert(isOwningHandle()); 51 return verifyChecksums(nativeHandle_); 52 } 53 54 /** 55 * If true, all data read from underlying storage will be 56 * verified against corresponding checksums. 57 * Default: true 58 * 59 * @param verifyChecksums if true, then checksum verification 60 * will be performed on every read. 61 * @return the reference to the current ReadOptions. 62 */ setVerifyChecksums( final boolean verifyChecksums)63 public ReadOptions setVerifyChecksums( 64 final boolean verifyChecksums) { 65 assert(isOwningHandle()); 66 setVerifyChecksums(nativeHandle_, verifyChecksums); 67 return this; 68 } 69 70 // TODO(yhchiang): this option seems to be block-based table only. 71 // move this to a better place? 72 /** 73 * Fill the cache when loading the block-based sst formated db. 74 * Callers may wish to set this field to false for bulk scans. 75 * Default: true 76 * 77 * @return true if the fill-cache behavior is on. 78 */ fillCache()79 public boolean fillCache() { 80 assert(isOwningHandle()); 81 return fillCache(nativeHandle_); 82 } 83 84 /** 85 * Fill the cache when loading the block-based sst formatted db. 86 * Callers may wish to set this field to false for bulk scans. 87 * Default: true 88 * 89 * @param fillCache if true, then fill-cache behavior will be 90 * performed. 91 * @return the reference to the current ReadOptions. 92 */ setFillCache(final boolean fillCache)93 public ReadOptions setFillCache(final boolean fillCache) { 94 assert(isOwningHandle()); 95 setFillCache(nativeHandle_, fillCache); 96 return this; 97 } 98 99 /** 100 * Returns the currently assigned Snapshot instance. 101 * 102 * @return the Snapshot assigned to this instance. If no Snapshot 103 * is assigned null. 104 */ snapshot()105 public Snapshot snapshot() { 106 assert(isOwningHandle()); 107 long snapshotHandle = snapshot(nativeHandle_); 108 if (snapshotHandle != 0) { 109 return new Snapshot(snapshotHandle); 110 } 111 return null; 112 } 113 114 /** 115 * <p>If "snapshot" is non-nullptr, read as of the supplied snapshot 116 * (which must belong to the DB that is being read and which must 117 * not have been released). If "snapshot" is nullptr, use an implicit 118 * snapshot of the state at the beginning of this read operation.</p> 119 * <p>Default: null</p> 120 * 121 * @param snapshot {@link Snapshot} instance 122 * @return the reference to the current ReadOptions. 123 */ setSnapshot(final Snapshot snapshot)124 public ReadOptions setSnapshot(final Snapshot snapshot) { 125 assert(isOwningHandle()); 126 if (snapshot != null) { 127 setSnapshot(nativeHandle_, snapshot.nativeHandle_); 128 } else { 129 setSnapshot(nativeHandle_, 0l); 130 } 131 return this; 132 } 133 134 /** 135 * Returns the current read tier. 136 * 137 * @return the read tier in use, by default {@link ReadTier#READ_ALL_TIER} 138 */ readTier()139 public ReadTier readTier() { 140 assert(isOwningHandle()); 141 return ReadTier.getReadTier(readTier(nativeHandle_)); 142 } 143 144 /** 145 * Specify if this read request should process data that ALREADY 146 * resides on a particular cache. If the required data is not 147 * found at the specified cache, then {@link RocksDBException} is thrown. 148 * 149 * @param readTier {@link ReadTier} instance 150 * @return the reference to the current ReadOptions. 151 */ setReadTier(final ReadTier readTier)152 public ReadOptions setReadTier(final ReadTier readTier) { 153 assert(isOwningHandle()); 154 setReadTier(nativeHandle_, readTier.getValue()); 155 return this; 156 } 157 158 /** 159 * Specify to create a tailing iterator -- a special iterator that has a 160 * view of the complete database (i.e. it can also be used to read newly 161 * added data) and is optimized for sequential reads. It will return records 162 * that were inserted into the database after the creation of the iterator. 163 * Default: false 164 * 165 * Not supported in {@code ROCKSDB_LITE} mode! 166 * 167 * @return true if tailing iterator is enabled. 168 */ tailing()169 public boolean tailing() { 170 assert(isOwningHandle()); 171 return tailing(nativeHandle_); 172 } 173 174 /** 175 * Specify to create a tailing iterator -- a special iterator that has a 176 * view of the complete database (i.e. it can also be used to read newly 177 * added data) and is optimized for sequential reads. It will return records 178 * that were inserted into the database after the creation of the iterator. 179 * Default: false 180 * Not supported in ROCKSDB_LITE mode! 181 * 182 * @param tailing if true, then tailing iterator will be enabled. 183 * @return the reference to the current ReadOptions. 184 */ setTailing(final boolean tailing)185 public ReadOptions setTailing(final boolean tailing) { 186 assert(isOwningHandle()); 187 setTailing(nativeHandle_, tailing); 188 return this; 189 } 190 191 /** 192 * Returns whether managed iterators will be used. 193 * 194 * @return the setting of whether managed iterators will be used, 195 * by default false 196 * 197 * @deprecated This options is not used anymore. 198 */ 199 @Deprecated managed()200 public boolean managed() { 201 assert(isOwningHandle()); 202 return managed(nativeHandle_); 203 } 204 205 /** 206 * Specify to create a managed iterator -- a special iterator that 207 * uses less resources by having the ability to free its underlying 208 * resources on request. 209 * 210 * @param managed if true, then managed iterators will be enabled. 211 * @return the reference to the current ReadOptions. 212 * 213 * @deprecated This options is not used anymore. 214 */ 215 @Deprecated setManaged(final boolean managed)216 public ReadOptions setManaged(final boolean managed) { 217 assert(isOwningHandle()); 218 setManaged(nativeHandle_, managed); 219 return this; 220 } 221 222 /** 223 * Returns whether a total seek order will be used 224 * 225 * @return the setting of whether a total seek order will be used 226 */ totalOrderSeek()227 public boolean totalOrderSeek() { 228 assert(isOwningHandle()); 229 return totalOrderSeek(nativeHandle_); 230 } 231 232 /** 233 * Enable a total order seek regardless of index format (e.g. hash index) 234 * used in the table. Some table format (e.g. plain table) may not support 235 * this option. 236 * 237 * @param totalOrderSeek if true, then total order seek will be enabled. 238 * @return the reference to the current ReadOptions. 239 */ setTotalOrderSeek(final boolean totalOrderSeek)240 public ReadOptions setTotalOrderSeek(final boolean totalOrderSeek) { 241 assert(isOwningHandle()); 242 setTotalOrderSeek(nativeHandle_, totalOrderSeek); 243 return this; 244 } 245 246 /** 247 * Returns whether the iterator only iterates over the same prefix as the seek 248 * 249 * @return the setting of whether the iterator only iterates over the same 250 * prefix as the seek, default is false 251 */ prefixSameAsStart()252 public boolean prefixSameAsStart() { 253 assert(isOwningHandle()); 254 return prefixSameAsStart(nativeHandle_); 255 } 256 257 /** 258 * Enforce that the iterator only iterates over the same prefix as the seek. 259 * This option is effective only for prefix seeks, i.e. prefix_extractor is 260 * non-null for the column family and {@link #totalOrderSeek()} is false. 261 * Unlike iterate_upper_bound, {@link #setPrefixSameAsStart(boolean)} only 262 * works within a prefix but in both directions. 263 * 264 * @param prefixSameAsStart if true, then the iterator only iterates over the 265 * same prefix as the seek 266 * @return the reference to the current ReadOptions. 267 */ setPrefixSameAsStart(final boolean prefixSameAsStart)268 public ReadOptions setPrefixSameAsStart(final boolean prefixSameAsStart) { 269 assert(isOwningHandle()); 270 setPrefixSameAsStart(nativeHandle_, prefixSameAsStart); 271 return this; 272 } 273 274 /** 275 * Returns whether the blocks loaded by the iterator will be pinned in memory 276 * 277 * @return the setting of whether the blocks loaded by the iterator will be 278 * pinned in memory 279 */ pinData()280 public boolean pinData() { 281 assert(isOwningHandle()); 282 return pinData(nativeHandle_); 283 } 284 285 /** 286 * Keep the blocks loaded by the iterator pinned in memory as long as the 287 * iterator is not deleted, If used when reading from tables created with 288 * BlockBasedTableOptions::use_delta_encoding = false, 289 * Iterator's property "rocksdb.iterator.is-key-pinned" is guaranteed to 290 * return 1. 291 * 292 * @param pinData if true, the blocks loaded by the iterator will be pinned 293 * @return the reference to the current ReadOptions. 294 */ setPinData(final boolean pinData)295 public ReadOptions setPinData(final boolean pinData) { 296 assert(isOwningHandle()); 297 setPinData(nativeHandle_, pinData); 298 return this; 299 } 300 301 /** 302 * If true, when PurgeObsoleteFile is called in CleanupIteratorState, we 303 * schedule a background job in the flush job queue and delete obsolete files 304 * in background. 305 * 306 * Default: false 307 * 308 * @return true when PurgeObsoleteFile is called in CleanupIteratorState 309 */ backgroundPurgeOnIteratorCleanup()310 public boolean backgroundPurgeOnIteratorCleanup() { 311 assert(isOwningHandle()); 312 return backgroundPurgeOnIteratorCleanup(nativeHandle_); 313 } 314 315 /** 316 * If true, when PurgeObsoleteFile is called in CleanupIteratorState, we 317 * schedule a background job in the flush job queue and delete obsolete files 318 * in background. 319 * 320 * Default: false 321 * 322 * @param backgroundPurgeOnIteratorCleanup true when PurgeObsoleteFile is 323 * called in CleanupIteratorState 324 * @return the reference to the current ReadOptions. 325 */ setBackgroundPurgeOnIteratorCleanup( final boolean backgroundPurgeOnIteratorCleanup)326 public ReadOptions setBackgroundPurgeOnIteratorCleanup( 327 final boolean backgroundPurgeOnIteratorCleanup) { 328 assert(isOwningHandle()); 329 setBackgroundPurgeOnIteratorCleanup(nativeHandle_, 330 backgroundPurgeOnIteratorCleanup); 331 return this; 332 } 333 334 /** 335 * If non-zero, NewIterator will create a new table reader which 336 * performs reads of the given size. Using a large size (> 2MB) can 337 * improve the performance of forward iteration on spinning disks. 338 * 339 * Default: 0 340 * 341 * @return The readahead size is bytes 342 */ readaheadSize()343 public long readaheadSize() { 344 assert(isOwningHandle()); 345 return readaheadSize(nativeHandle_); 346 } 347 348 /** 349 * If non-zero, NewIterator will create a new table reader which 350 * performs reads of the given size. Using a large size (> 2MB) can 351 * improve the performance of forward iteration on spinning disks. 352 * 353 * Default: 0 354 * 355 * @param readaheadSize The readahead size is bytes 356 * @return the reference to the current ReadOptions. 357 */ setReadaheadSize(final long readaheadSize)358 public ReadOptions setReadaheadSize(final long readaheadSize) { 359 assert(isOwningHandle()); 360 setReadaheadSize(nativeHandle_, readaheadSize); 361 return this; 362 } 363 364 /** 365 * A threshold for the number of keys that can be skipped before failing an 366 * iterator seek as incomplete. 367 * 368 * @return the number of keys that can be skipped 369 * before failing an iterator seek as incomplete. 370 */ maxSkippableInternalKeys()371 public long maxSkippableInternalKeys() { 372 assert(isOwningHandle()); 373 return maxSkippableInternalKeys(nativeHandle_); 374 } 375 376 /** 377 * A threshold for the number of keys that can be skipped before failing an 378 * iterator seek as incomplete. The default value of 0 should be used to 379 * never fail a request as incomplete, even on skipping too many keys. 380 * 381 * Default: 0 382 * 383 * @param maxSkippableInternalKeys the number of keys that can be skipped 384 * before failing an iterator seek as incomplete. 385 * 386 * @return the reference to the current ReadOptions. 387 */ setMaxSkippableInternalKeys( final long maxSkippableInternalKeys)388 public ReadOptions setMaxSkippableInternalKeys( 389 final long maxSkippableInternalKeys) { 390 assert(isOwningHandle()); 391 setMaxSkippableInternalKeys(nativeHandle_, maxSkippableInternalKeys); 392 return this; 393 } 394 395 /** 396 * If true, keys deleted using the DeleteRange() API will be visible to 397 * readers until they are naturally deleted during compaction. This improves 398 * read performance in DBs with many range deletions. 399 * 400 * Default: false 401 * 402 * @return true if keys deleted using the DeleteRange() API will be visible 403 */ ignoreRangeDeletions()404 public boolean ignoreRangeDeletions() { 405 assert(isOwningHandle()); 406 return ignoreRangeDeletions(nativeHandle_); 407 } 408 409 /** 410 * If true, keys deleted using the DeleteRange() API will be visible to 411 * readers until they are naturally deleted during compaction. This improves 412 * read performance in DBs with many range deletions. 413 * 414 * Default: false 415 * 416 * @param ignoreRangeDeletions true if keys deleted using the DeleteRange() 417 * API should be visible 418 * @return the reference to the current ReadOptions. 419 */ setIgnoreRangeDeletions(final boolean ignoreRangeDeletions)420 public ReadOptions setIgnoreRangeDeletions(final boolean ignoreRangeDeletions) { 421 assert(isOwningHandle()); 422 setIgnoreRangeDeletions(nativeHandle_, ignoreRangeDeletions); 423 return this; 424 } 425 426 /** 427 * Defines the smallest key at which the backward 428 * iterator can return an entry. Once the bound is passed, 429 * {@link RocksIterator#isValid()} will be false. 430 * 431 * The lower bound is inclusive i.e. the bound value is a valid 432 * entry. 433 * 434 * If prefix_extractor is not null, the Seek target and `iterate_lower_bound` 435 * need to have the same prefix. This is because ordering is not guaranteed 436 * outside of prefix domain. 437 * 438 * Default: null 439 * 440 * @param iterateLowerBound Slice representing the upper bound 441 * @return the reference to the current ReadOptions. 442 */ setIterateLowerBound(final Slice iterateLowerBound)443 public ReadOptions setIterateLowerBound(final Slice iterateLowerBound) { 444 assert(isOwningHandle()); 445 if (iterateLowerBound != null) { 446 // Hold onto a reference so it doesn't get garbage collected out from under us. 447 iterateLowerBoundSlice_ = iterateLowerBound; 448 setIterateLowerBound(nativeHandle_, iterateLowerBoundSlice_.getNativeHandle()); 449 } 450 return this; 451 } 452 453 /** 454 * Returns the smallest key at which the backward 455 * iterator can return an entry. 456 * 457 * The lower bound is inclusive i.e. the bound value is a valid entry. 458 * 459 * @return the smallest key, or null if there is no lower bound defined. 460 */ iterateLowerBound()461 public Slice iterateLowerBound() { 462 assert(isOwningHandle()); 463 final long lowerBoundSliceHandle = iterateLowerBound(nativeHandle_); 464 if (lowerBoundSliceHandle != 0) { 465 // Disown the new slice - it's owned by the C++ side of the JNI boundary 466 // from the perspective of this method. 467 return new Slice(lowerBoundSliceHandle, false); 468 } 469 return null; 470 } 471 472 /** 473 * Defines the extent up to which the forward iterator 474 * can returns entries. Once the bound is reached, 475 * {@link RocksIterator#isValid()} will be false. 476 * 477 * The upper bound is exclusive i.e. the bound value is not a valid entry. 478 * 479 * If prefix_extractor is not null, the Seek target and iterate_upper_bound 480 * need to have the same prefix. This is because ordering is not guaranteed 481 * outside of prefix domain. 482 * 483 * Default: null 484 * 485 * @param iterateUpperBound Slice representing the upper bound 486 * @return the reference to the current ReadOptions. 487 */ setIterateUpperBound(final Slice iterateUpperBound)488 public ReadOptions setIterateUpperBound(final Slice iterateUpperBound) { 489 assert(isOwningHandle()); 490 if (iterateUpperBound != null) { 491 // Hold onto a reference so it doesn't get garbage collected out from under us. 492 iterateUpperBoundSlice_ = iterateUpperBound; 493 setIterateUpperBound(nativeHandle_, iterateUpperBoundSlice_.getNativeHandle()); 494 } 495 return this; 496 } 497 498 /** 499 * Returns the largest key at which the forward 500 * iterator can return an entry. 501 * 502 * The upper bound is exclusive i.e. the bound value is not a valid entry. 503 * 504 * @return the largest key, or null if there is no upper bound defined. 505 */ iterateUpperBound()506 public Slice iterateUpperBound() { 507 assert(isOwningHandle()); 508 final long upperBoundSliceHandle = iterateUpperBound(nativeHandle_); 509 if (upperBoundSliceHandle != 0) { 510 // Disown the new slice - it's owned by the C++ side of the JNI boundary 511 // from the perspective of this method. 512 return new Slice(upperBoundSliceHandle, false); 513 } 514 return null; 515 } 516 517 /** 518 * A callback to determine whether relevant keys for this scan exist in a 519 * given table based on the table's properties. The callback is passed the 520 * properties of each table during iteration. If the callback returns false, 521 * the table will not be scanned. This option only affects Iterators and has 522 * no impact on point lookups. 523 * 524 * Default: null (every table will be scanned) 525 * 526 * @param tableFilter the table filter for the callback. 527 * 528 * @return the reference to the current ReadOptions. 529 */ setTableFilter(final AbstractTableFilter tableFilter)530 public ReadOptions setTableFilter(final AbstractTableFilter tableFilter) { 531 assert(isOwningHandle()); 532 setTableFilter(nativeHandle_, tableFilter.nativeHandle_); 533 return this; 534 } 535 536 /** 537 * Needed to support differential snapshots. Has 2 effects: 538 * 1) Iterator will skip all internal keys with seqnum < iter_start_seqnum 539 * 2) if this param > 0 iterator will return INTERNAL keys instead of user 540 * keys; e.g. return tombstones as well. 541 * 542 * Default: 0 (don't filter by seqnum, return user keys) 543 * 544 * @param startSeqnum the starting sequence number. 545 * 546 * @return the reference to the current ReadOptions. 547 */ setIterStartSeqnum(final long startSeqnum)548 public ReadOptions setIterStartSeqnum(final long startSeqnum) { 549 assert(isOwningHandle()); 550 setIterStartSeqnum(nativeHandle_, startSeqnum); 551 return this; 552 } 553 554 /** 555 * Returns the starting Sequence Number of any iterator. 556 * See {@link #setIterStartSeqnum(long)}. 557 * 558 * @return the starting sequence number of any iterator. 559 */ iterStartSeqnum()560 public long iterStartSeqnum() { 561 assert(isOwningHandle()); 562 return iterStartSeqnum(nativeHandle_); 563 } 564 565 // instance variables 566 // NOTE: If you add new member variables, please update the copy constructor above! 567 // 568 // Hold a reference to any iterate lower or upper bound that was set on this 569 // object until we're destroyed or it's overwritten. That way the caller can 570 // freely leave scope without us losing the Java Slice object, which during 571 // close() would also reap its associated rocksdb::Slice native object since 572 // it's possibly (likely) to be an owning handle. 573 private Slice iterateLowerBoundSlice_; 574 private Slice iterateUpperBoundSlice_; 575 newReadOptions()576 private native static long newReadOptions(); newReadOptions(final boolean verifyChecksums, final boolean fillCache)577 private native static long newReadOptions(final boolean verifyChecksums, 578 final boolean fillCache); copyReadOptions(long handle)579 private native static long copyReadOptions(long handle); disposeInternal(final long handle)580 @Override protected final native void disposeInternal(final long handle); 581 verifyChecksums(long handle)582 private native boolean verifyChecksums(long handle); setVerifyChecksums(long handle, boolean verifyChecksums)583 private native void setVerifyChecksums(long handle, boolean verifyChecksums); fillCache(long handle)584 private native boolean fillCache(long handle); setFillCache(long handle, boolean fillCache)585 private native void setFillCache(long handle, boolean fillCache); snapshot(long handle)586 private native long snapshot(long handle); setSnapshot(long handle, long snapshotHandle)587 private native void setSnapshot(long handle, long snapshotHandle); readTier(long handle)588 private native byte readTier(long handle); setReadTier(long handle, byte readTierValue)589 private native void setReadTier(long handle, byte readTierValue); tailing(long handle)590 private native boolean tailing(long handle); setTailing(long handle, boolean tailing)591 private native void setTailing(long handle, boolean tailing); managed(long handle)592 private native boolean managed(long handle); setManaged(long handle, boolean managed)593 private native void setManaged(long handle, boolean managed); totalOrderSeek(long handle)594 private native boolean totalOrderSeek(long handle); setTotalOrderSeek(long handle, boolean totalOrderSeek)595 private native void setTotalOrderSeek(long handle, boolean totalOrderSeek); prefixSameAsStart(long handle)596 private native boolean prefixSameAsStart(long handle); setPrefixSameAsStart(long handle, boolean prefixSameAsStart)597 private native void setPrefixSameAsStart(long handle, boolean prefixSameAsStart); pinData(long handle)598 private native boolean pinData(long handle); setPinData(long handle, boolean pinData)599 private native void setPinData(long handle, boolean pinData); backgroundPurgeOnIteratorCleanup(final long handle)600 private native boolean backgroundPurgeOnIteratorCleanup(final long handle); setBackgroundPurgeOnIteratorCleanup(final long handle, final boolean backgroundPurgeOnIteratorCleanup)601 private native void setBackgroundPurgeOnIteratorCleanup(final long handle, 602 final boolean backgroundPurgeOnIteratorCleanup); readaheadSize(final long handle)603 private native long readaheadSize(final long handle); setReadaheadSize(final long handle, final long readaheadSize)604 private native void setReadaheadSize(final long handle, 605 final long readaheadSize); maxSkippableInternalKeys(final long handle)606 private native long maxSkippableInternalKeys(final long handle); setMaxSkippableInternalKeys(final long handle, final long maxSkippableInternalKeys)607 private native void setMaxSkippableInternalKeys(final long handle, 608 final long maxSkippableInternalKeys); ignoreRangeDeletions(final long handle)609 private native boolean ignoreRangeDeletions(final long handle); setIgnoreRangeDeletions(final long handle, final boolean ignoreRangeDeletions)610 private native void setIgnoreRangeDeletions(final long handle, 611 final boolean ignoreRangeDeletions); setIterateUpperBound(final long handle, final long upperBoundSliceHandle)612 private native void setIterateUpperBound(final long handle, 613 final long upperBoundSliceHandle); iterateUpperBound(final long handle)614 private native long iterateUpperBound(final long handle); setIterateLowerBound(final long handle, final long lowerBoundSliceHandle)615 private native void setIterateLowerBound(final long handle, 616 final long lowerBoundSliceHandle); iterateLowerBound(final long handle)617 private native long iterateLowerBound(final long handle); setTableFilter(final long handle, final long tableFilterHandle)618 private native void setTableFilter(final long handle, 619 final long tableFilterHandle); setIterStartSeqnum(final long handle, final long seqNum)620 private native void setIterStartSeqnum(final long handle, final long seqNum); iterStartSeqnum(final long handle)621 private native long iterStartSeqnum(final long handle); 622 } 623