@nxtedition/rocksdb 7.1.33 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BUILDING.md +2 -2
- package/binding.cc +0 -147
- package/deps/rocksdb/rocksdb/cache/clock_cache.cc +402 -345
- package/deps/rocksdb/rocksdb/cache/clock_cache.h +121 -64
- package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +28 -18
- package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.cc +1 -0
- package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.h +2 -0
- package/deps/rocksdb/rocksdb/db/builder.cc +2 -1
- package/deps/rocksdb/rocksdb/db/c.cc +563 -673
- package/deps/rocksdb/rocksdb/db/c_test.c +168 -169
- package/deps/rocksdb/rocksdb/db/column_family.cc +16 -15
- package/deps/rocksdb/rocksdb/db/column_family.h +7 -7
- package/deps/rocksdb/rocksdb/db/column_family_test.cc +17 -28
- package/deps/rocksdb/rocksdb/db/compact_files_test.cc +4 -9
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +8 -3
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +114 -0
- package/deps/rocksdb/rocksdb/db/comparator_db_test.cc +2 -3
- package/deps/rocksdb/rocksdb/db/convenience.cc +3 -5
- package/deps/rocksdb/rocksdb/db/corruption_test.cc +10 -14
- package/deps/rocksdb/rocksdb/db/cuckoo_table_db_test.cc +9 -13
- package/deps/rocksdb/rocksdb/db/db_basic_test.cc +2 -2
- package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +2 -2
- package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +14 -16
- package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +52 -72
- package/deps/rocksdb/rocksdb/db/db_dynamic_level_test.cc +2 -2
- package/deps/rocksdb/rocksdb/db/db_encryption_test.cc +12 -12
- package/deps/rocksdb/rocksdb/db/db_filesnapshot.cc +1 -2
- package/deps/rocksdb/rocksdb/db/db_flush_test.cc +3 -3
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +1 -12
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +3 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +26 -0
- package/deps/rocksdb/rocksdb/db/db_info_dumper.cc +1 -0
- package/deps/rocksdb/rocksdb/db/db_iter.cc +12 -6
- package/deps/rocksdb/rocksdb/db/db_iter.h +1 -0
- package/deps/rocksdb/rocksdb/db/db_iter_stress_test.cc +6 -7
- package/deps/rocksdb/rocksdb/db/db_iter_test.cc +10 -8
- package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +15 -13
- package/deps/rocksdb/rocksdb/db/db_log_iter_test.cc +7 -9
- package/deps/rocksdb/rocksdb/db/db_logical_block_size_cache_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/db_merge_operand_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_merge_operator_test.cc +2 -4
- package/deps/rocksdb/rocksdb/db/db_options_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/db_properties_test.cc +7 -4
- package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +7 -5
- package/deps/rocksdb/rocksdb/db/db_secondary_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_statistics_test.cc +8 -6
- package/deps/rocksdb/rocksdb/db/db_table_properties_test.cc +18 -23
- package/deps/rocksdb/rocksdb/db/db_tailing_iter_test.cc +3 -5
- package/deps/rocksdb/rocksdb/db/db_test.cc +10 -5
- package/deps/rocksdb/rocksdb/db/db_test2.cc +172 -169
- package/deps/rocksdb/rocksdb/db/db_test_util.cc +68 -66
- package/deps/rocksdb/rocksdb/db/db_test_util.h +1 -3
- package/deps/rocksdb/rocksdb/db/db_universal_compaction_test.cc +31 -39
- package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +182 -2
- package/deps/rocksdb/rocksdb/db/db_write_test.cc +43 -40
- package/deps/rocksdb/rocksdb/db/dbformat.h +15 -0
- package/deps/rocksdb/rocksdb/db/dbformat_test.cc +35 -34
- package/deps/rocksdb/rocksdb/db/deletefile_test.cc +10 -11
- package/deps/rocksdb/rocksdb/db/error_handler.cc +6 -6
- package/deps/rocksdb/rocksdb/db/error_handler.h +93 -94
- package/deps/rocksdb/rocksdb/db/event_helpers.cc +1 -1
- package/deps/rocksdb/rocksdb/db/event_helpers.h +3 -3
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +16 -17
- package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +2 -2
- package/deps/rocksdb/rocksdb/db/fault_injection_test.cc +1 -2
- package/deps/rocksdb/rocksdb/db/file_indexer.cc +2 -0
- package/deps/rocksdb/rocksdb/db/file_indexer.h +2 -1
- package/deps/rocksdb/rocksdb/db/file_indexer_test.cc +4 -2
- package/deps/rocksdb/rocksdb/db/filename_test.cc +27 -29
- package/deps/rocksdb/rocksdb/db/flush_job.cc +7 -13
- package/deps/rocksdb/rocksdb/db/flush_job_test.cc +2 -2
- package/deps/rocksdb/rocksdb/db/forward_iterator.cc +15 -21
- package/deps/rocksdb/rocksdb/db/forward_iterator.h +7 -6
- package/deps/rocksdb/rocksdb/db/forward_iterator_bench.cc +4 -2
- package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +2 -2
- package/deps/rocksdb/rocksdb/db/internal_stats.cc +59 -14
- package/deps/rocksdb/rocksdb/db/internal_stats.h +27 -11
- package/deps/rocksdb/rocksdb/db/job_context.h +5 -6
- package/deps/rocksdb/rocksdb/db/listener_test.cc +21 -23
- package/deps/rocksdb/rocksdb/db/log_reader.cc +7 -11
- package/deps/rocksdb/rocksdb/db/log_reader.h +4 -6
- package/deps/rocksdb/rocksdb/db/log_test.cc +6 -12
- package/deps/rocksdb/rocksdb/db/log_writer.h +1 -1
- package/deps/rocksdb/rocksdb/db/logs_with_prep_tracker.h +0 -1
- package/deps/rocksdb/rocksdb/db/lookup_key.h +4 -1
- package/deps/rocksdb/rocksdb/db/malloc_stats.cc +2 -1
- package/deps/rocksdb/rocksdb/db/manual_compaction_test.cc +3 -5
- package/deps/rocksdb/rocksdb/db/memtable.cc +34 -22
- package/deps/rocksdb/rocksdb/db/memtable.h +4 -6
- package/deps/rocksdb/rocksdb/db/memtable_list.cc +7 -0
- package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +37 -13
- package/deps/rocksdb/rocksdb/db/merge_context.h +1 -0
- package/deps/rocksdb/rocksdb/db/merge_helper.cc +128 -14
- package/deps/rocksdb/rocksdb/db/merge_helper.h +15 -7
- package/deps/rocksdb/rocksdb/db/merge_helper_test.cc +2 -1
- package/deps/rocksdb/rocksdb/db/merge_operator.cc +5 -6
- package/deps/rocksdb/rocksdb/db/obsolete_files_test.cc +4 -3
- package/deps/rocksdb/rocksdb/db/options_file_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/perf_context_test.cc +55 -43
- package/deps/rocksdb/rocksdb/db/plain_table_db_test.cc +288 -299
- package/deps/rocksdb/rocksdb/db/prefix_test.cc +22 -27
- package/deps/rocksdb/rocksdb/db/range_del_aggregator.cc +1 -1
- package/deps/rocksdb/rocksdb/db/range_del_aggregator_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/repair.cc +7 -8
- package/deps/rocksdb/rocksdb/db/repair_test.cc +3 -4
- package/deps/rocksdb/rocksdb/db/snapshot_impl.cc +4 -5
- package/deps/rocksdb/rocksdb/db/snapshot_impl.h +10 -4
- package/deps/rocksdb/rocksdb/db/table_cache.cc +3 -4
- package/deps/rocksdb/rocksdb/db/table_properties_collector.cc +6 -7
- package/deps/rocksdb/rocksdb/db/table_properties_collector_test.cc +22 -22
- package/deps/rocksdb/rocksdb/db/transaction_log_impl.cc +12 -12
- package/deps/rocksdb/rocksdb/db/transaction_log_impl.h +6 -8
- package/deps/rocksdb/rocksdb/db/trim_history_scheduler.h +2 -0
- package/deps/rocksdb/rocksdb/db/version_builder_test.cc +3 -3
- package/deps/rocksdb/rocksdb/db/version_edit.cc +2 -5
- package/deps/rocksdb/rocksdb/db/version_edit.h +8 -12
- package/deps/rocksdb/rocksdb/db/version_set.cc +74 -102
- package/deps/rocksdb/rocksdb/db/version_set.h +8 -10
- package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +0 -5
- package/deps/rocksdb/rocksdb/db/version_set_test.cc +47 -45
- package/deps/rocksdb/rocksdb/db/wal_manager.cc +6 -5
- package/deps/rocksdb/rocksdb/db/wal_manager.h +2 -2
- package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +4 -3
- package/deps/rocksdb/rocksdb/db/wide/db_wide_basic_test.cc +144 -61
- package/deps/rocksdb/rocksdb/db/write_batch.cc +41 -24
- package/deps/rocksdb/rocksdb/db/write_batch_internal.h +2 -7
- package/deps/rocksdb/rocksdb/db/write_batch_test.cc +105 -104
- package/deps/rocksdb/rocksdb/db/write_callback_test.cc +5 -4
- package/deps/rocksdb/rocksdb/db/write_controller.h +1 -0
- package/deps/rocksdb/rocksdb/db/write_controller_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/write_thread.cc +8 -6
- package/deps/rocksdb/rocksdb/env/io_posix.h +6 -0
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +134 -65
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +29 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/compaction_filter.h +1 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/db.h +1 -4
- package/deps/rocksdb/rocksdb/include/rocksdb/merge_operator.h +1 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/stackable_db.h +4 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +14 -4
- package/deps/rocksdb/rocksdb/table/get_context.cc +52 -7
- package/deps/rocksdb/rocksdb/table/get_context.h +1 -2
- package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +13 -0
- package/deps/rocksdb/rocksdb/util/crc32c_arm64.cc +36 -4
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +6 -6
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.h +23 -28
- package/deps/rocksdb/rocksdb/utilities/transactions/write_committed_transaction_ts_test.cc +11 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_test.cc +19 -17
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.cc +10 -7
- package/index.js +3 -195
- package/package.json +2 -4
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.node +0 -0
- package/common.js +0 -7
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
namespace ROCKSDB_NAMESPACE {
|
|
29
29
|
|
|
30
|
-
namespace
|
|
30
|
+
namespace clock_cache {
|
|
31
31
|
|
|
32
32
|
// Forward declaration of friend class.
|
|
33
33
|
class ClockCacheTest;
|
|
@@ -311,6 +311,14 @@ struct ClockHandleBasicData {
|
|
|
311
311
|
UniqueId64x2 hashed_key = kNullUniqueId64x2;
|
|
312
312
|
size_t total_charge = 0;
|
|
313
313
|
|
|
314
|
+
// For total_charge_and_flags
|
|
315
|
+
// "Detached" means the handle is allocated separately from hash table.
|
|
316
|
+
static constexpr uint64_t kFlagDetached = uint64_t{1} << 63;
|
|
317
|
+
// Extract just the total charge
|
|
318
|
+
static constexpr uint64_t kTotalChargeMask = kFlagDetached - 1;
|
|
319
|
+
|
|
320
|
+
inline size_t GetTotalCharge() const { return total_charge; }
|
|
321
|
+
|
|
314
322
|
// Calls deleter (if non-null) on cache key and value
|
|
315
323
|
void FreeData() const;
|
|
316
324
|
|
|
@@ -318,9 +326,7 @@ struct ClockHandleBasicData {
|
|
|
318
326
|
const UniqueId64x2& GetHash() const { return hashed_key; }
|
|
319
327
|
};
|
|
320
328
|
|
|
321
|
-
|
|
322
|
-
// clock_cache.cc)
|
|
323
|
-
struct ALIGN_AS(64U) ClockHandle : public ClockHandleBasicData {
|
|
329
|
+
struct ClockHandle : public ClockHandleBasicData {
|
|
324
330
|
// Constants for handling the atomic `meta` word, which tracks most of the
|
|
325
331
|
// state of the handle. The meta word looks like this:
|
|
326
332
|
// low bits high bits
|
|
@@ -372,32 +378,54 @@ struct ALIGN_AS(64U) ClockHandle : public ClockHandleBasicData {
|
|
|
372
378
|
|
|
373
379
|
// See above
|
|
374
380
|
std::atomic<uint64_t> meta{};
|
|
375
|
-
// The number of elements that hash to this slot or a lower one, but wind
|
|
376
|
-
// up in this slot or a higher one.
|
|
377
|
-
std::atomic<uint32_t> displacements{};
|
|
378
381
|
|
|
379
|
-
//
|
|
380
|
-
|
|
382
|
+
// Anticipating use for SecondaryCache support
|
|
383
|
+
void* reserved_for_future_use = nullptr;
|
|
381
384
|
}; // struct ClockHandle
|
|
382
385
|
|
|
383
|
-
class
|
|
386
|
+
class HyperClockTable {
|
|
384
387
|
public:
|
|
385
|
-
|
|
386
|
-
|
|
388
|
+
// Target size to be exactly a common cache line size (see static_assert in
|
|
389
|
+
// clock_cache.cc)
|
|
390
|
+
struct ALIGN_AS(64U) HandleImpl : public ClockHandle {
|
|
391
|
+
// The number of elements that hash to this slot or a lower one, but wind
|
|
392
|
+
// up in this slot or a higher one.
|
|
393
|
+
std::atomic<uint32_t> displacements{};
|
|
394
|
+
|
|
395
|
+
// Whether this is a "deteched" handle that is independently allocated
|
|
396
|
+
// with `new` (so must be deleted with `delete`).
|
|
397
|
+
// TODO: ideally this would be packed into some other data field, such
|
|
398
|
+
// as upper bits of total_charge, but that incurs a measurable performance
|
|
399
|
+
// regression.
|
|
400
|
+
bool detached = false;
|
|
401
|
+
|
|
402
|
+
inline bool IsDetached() const { return detached; }
|
|
403
|
+
|
|
404
|
+
inline void SetDetached() { detached = true; }
|
|
405
|
+
}; // struct HandleImpl
|
|
406
|
+
|
|
407
|
+
struct Opts {
|
|
408
|
+
size_t estimated_value_size;
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
HyperClockTable(size_t capacity, bool strict_capacity_limit,
|
|
412
|
+
CacheMetadataChargePolicy metadata_charge_policy,
|
|
413
|
+
const Opts& opts);
|
|
414
|
+
~HyperClockTable();
|
|
387
415
|
|
|
388
|
-
Status Insert(const ClockHandleBasicData& proto,
|
|
416
|
+
Status Insert(const ClockHandleBasicData& proto, HandleImpl** handle,
|
|
389
417
|
Cache::Priority priority, size_t capacity,
|
|
390
418
|
bool strict_capacity_limit);
|
|
391
419
|
|
|
392
|
-
|
|
420
|
+
HandleImpl* Lookup(const UniqueId64x2& hashed_key);
|
|
393
421
|
|
|
394
|
-
bool Release(
|
|
422
|
+
bool Release(HandleImpl* handle, bool useful, bool erase_if_last_ref);
|
|
395
423
|
|
|
396
|
-
void Ref(
|
|
424
|
+
void Ref(HandleImpl& handle);
|
|
397
425
|
|
|
398
426
|
void Erase(const UniqueId64x2& hashed_key);
|
|
399
427
|
|
|
400
|
-
void ConstApplyToEntriesRange(std::function<void(const
|
|
428
|
+
void ConstApplyToEntriesRange(std::function<void(const HandleImpl&)> func,
|
|
401
429
|
size_t index_begin, size_t index_end,
|
|
402
430
|
bool apply_if_will_be_deleted) const;
|
|
403
431
|
|
|
@@ -407,8 +435,6 @@ class ClockHandleTable {
|
|
|
407
435
|
|
|
408
436
|
int GetLengthBits() const { return length_bits_; }
|
|
409
437
|
|
|
410
|
-
size_t GetOccupancyLimit() const { return occupancy_limit_; }
|
|
411
|
-
|
|
412
438
|
size_t GetOccupancy() const {
|
|
413
439
|
return occupancy_.load(std::memory_order_relaxed);
|
|
414
440
|
}
|
|
@@ -420,8 +446,8 @@ class ClockHandleTable {
|
|
|
420
446
|
}
|
|
421
447
|
|
|
422
448
|
// Acquire/release N references
|
|
423
|
-
void TEST_RefN(
|
|
424
|
-
void TEST_ReleaseN(
|
|
449
|
+
void TEST_RefN(HandleImpl& handle, size_t n);
|
|
450
|
+
void TEST_ReleaseN(HandleImpl* handle, size_t n);
|
|
425
451
|
|
|
426
452
|
private: // functions
|
|
427
453
|
// Returns x mod 2^{length_bits_}.
|
|
@@ -432,8 +458,8 @@ class ClockHandleTable {
|
|
|
432
458
|
// Runs the clock eviction algorithm trying to reclaim at least
|
|
433
459
|
// requested_charge. Returns how much is evicted, which could be less
|
|
434
460
|
// if it appears impossible to evict the requested amount without blocking.
|
|
435
|
-
void Evict(size_t requested_charge, size_t* freed_charge,
|
|
436
|
-
|
|
461
|
+
inline void Evict(size_t requested_charge, size_t* freed_charge,
|
|
462
|
+
size_t* freed_count);
|
|
437
463
|
|
|
438
464
|
// Returns the first slot in the probe sequence, starting from the given
|
|
439
465
|
// probe number, with a handle e such that match(e) is true. At every
|
|
@@ -446,15 +472,54 @@ class ClockHandleTable {
|
|
|
446
472
|
// value of probe is one more than the last non-aborting probe during the
|
|
447
473
|
// call. This is so that that the variable can be used to keep track of
|
|
448
474
|
// progress across consecutive calls to FindSlot.
|
|
449
|
-
inline
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
475
|
+
inline HandleImpl* FindSlot(const UniqueId64x2& hashed_key,
|
|
476
|
+
std::function<bool(HandleImpl*)> match,
|
|
477
|
+
std::function<bool(HandleImpl*)> stop,
|
|
478
|
+
std::function<void(HandleImpl*)> update,
|
|
479
|
+
size_t& probe);
|
|
454
480
|
|
|
455
481
|
// Re-decrement all displacements in probe path starting from beginning
|
|
456
482
|
// until (not including) the given handle
|
|
457
|
-
void Rollback(const UniqueId64x2& hashed_key, const
|
|
483
|
+
inline void Rollback(const UniqueId64x2& hashed_key, const HandleImpl* h);
|
|
484
|
+
|
|
485
|
+
// Subtracts `total_charge` from `usage_` and 1 from `occupancy_`.
|
|
486
|
+
// Ideally this comes after releasing the entry itself so that we
|
|
487
|
+
// actually have the available occupancy/usage that is claimed.
|
|
488
|
+
// However, that means total_charge has to be saved from the handle
|
|
489
|
+
// before releasing it so that it can be provided to this function.
|
|
490
|
+
inline void ReclaimEntryUsage(size_t total_charge);
|
|
491
|
+
|
|
492
|
+
// Helper for updating `usage_` for new entry with given `total_charge`
|
|
493
|
+
// and evicting if needed under strict_capacity_limit=true rules. This
|
|
494
|
+
// means the operation might fail with Status::MemoryLimit. If
|
|
495
|
+
// `need_evict_for_occupancy`, then eviction of at least one entry is
|
|
496
|
+
// required, and the operation should fail if not possible.
|
|
497
|
+
// NOTE: Otherwise, occupancy_ is not managed in this function
|
|
498
|
+
inline Status ChargeUsageMaybeEvictStrict(size_t total_charge,
|
|
499
|
+
size_t capacity,
|
|
500
|
+
bool need_evict_for_occupancy);
|
|
501
|
+
|
|
502
|
+
// Helper for updating `usage_` for new entry with given `total_charge`
|
|
503
|
+
// and evicting if needed under strict_capacity_limit=false rules. This
|
|
504
|
+
// means that updating `usage_` always succeeds even if forced to exceed
|
|
505
|
+
// capacity. If `need_evict_for_occupancy`, then eviction of at least one
|
|
506
|
+
// entry is required, and the operation should return false if such eviction
|
|
507
|
+
// is not possible. `usage_` is not updated in that case. Otherwise, returns
|
|
508
|
+
// true, indicating success.
|
|
509
|
+
// NOTE: occupancy_ is not managed in this function
|
|
510
|
+
inline bool ChargeUsageMaybeEvictNonStrict(size_t total_charge,
|
|
511
|
+
size_t capacity,
|
|
512
|
+
bool need_evict_for_occupancy);
|
|
513
|
+
|
|
514
|
+
// Creates a "detached" handle for returning from an Insert operation that
|
|
515
|
+
// cannot be completed by actually inserting into the table.
|
|
516
|
+
// Updates `detached_usage_` but not `usage_` nor `occupancy_`.
|
|
517
|
+
inline HandleImpl* DetachedInsert(const ClockHandleBasicData& proto);
|
|
518
|
+
|
|
519
|
+
// Returns the number of bits used to hash an element in the hash
|
|
520
|
+
// table.
|
|
521
|
+
static int CalcHashBits(size_t capacity, size_t estimated_value_size,
|
|
522
|
+
CacheMetadataChargePolicy metadata_charge_policy);
|
|
458
523
|
|
|
459
524
|
private: // data
|
|
460
525
|
// Number of hash bits used for table index.
|
|
@@ -468,7 +533,7 @@ class ClockHandleTable {
|
|
|
468
533
|
const size_t occupancy_limit_;
|
|
469
534
|
|
|
470
535
|
// Array of slots comprising the hash table.
|
|
471
|
-
const std::unique_ptr<
|
|
536
|
+
const std::unique_ptr<HandleImpl[]> array_;
|
|
472
537
|
|
|
473
538
|
// We partition the following members into different cache lines
|
|
474
539
|
// to avoid false sharing among Lookup, Release, Erase and Insert
|
|
@@ -487,17 +552,18 @@ class ClockHandleTable {
|
|
|
487
552
|
|
|
488
553
|
// Part of usage by detached entries (not in table)
|
|
489
554
|
std::atomic<size_t> detached_usage_{};
|
|
490
|
-
}; // class
|
|
555
|
+
}; // class HyperClockTable
|
|
491
556
|
|
|
492
557
|
// A single shard of sharded cache.
|
|
558
|
+
template <class Table>
|
|
493
559
|
class ALIGN_AS(CACHE_LINE_SIZE) ClockCacheShard final : public CacheShardBase {
|
|
494
560
|
public:
|
|
495
|
-
ClockCacheShard(size_t capacity,
|
|
496
|
-
|
|
497
|
-
|
|
561
|
+
ClockCacheShard(size_t capacity, bool strict_capacity_limit,
|
|
562
|
+
CacheMetadataChargePolicy metadata_charge_policy,
|
|
563
|
+
const typename Table::Opts& opts);
|
|
498
564
|
|
|
499
565
|
// For CacheShard concept
|
|
500
|
-
using HandleImpl =
|
|
566
|
+
using HandleImpl = typename Table::HandleImpl;
|
|
501
567
|
// Hash is lossless hash of 128-bit key
|
|
502
568
|
using HashVal = UniqueId64x2;
|
|
503
569
|
using HashCref = const HashVal&;
|
|
@@ -532,16 +598,16 @@ class ALIGN_AS(CACHE_LINE_SIZE) ClockCacheShard final : public CacheShardBase {
|
|
|
532
598
|
void SetStrictCapacityLimit(bool strict_capacity_limit);
|
|
533
599
|
|
|
534
600
|
Status Insert(const Slice& key, const UniqueId64x2& hashed_key, void* value,
|
|
535
|
-
size_t charge, Cache::DeleterFn deleter,
|
|
601
|
+
size_t charge, Cache::DeleterFn deleter, HandleImpl** handle,
|
|
536
602
|
Cache::Priority priority);
|
|
537
603
|
|
|
538
|
-
|
|
604
|
+
HandleImpl* Lookup(const Slice& key, const UniqueId64x2& hashed_key);
|
|
539
605
|
|
|
540
|
-
bool Release(
|
|
606
|
+
bool Release(HandleImpl* handle, bool useful, bool erase_if_last_ref);
|
|
541
607
|
|
|
542
|
-
bool Release(
|
|
608
|
+
bool Release(HandleImpl* handle, bool erase_if_last_ref = false);
|
|
543
609
|
|
|
544
|
-
bool Ref(
|
|
610
|
+
bool Ref(HandleImpl* handle);
|
|
545
611
|
|
|
546
612
|
void Erase(const Slice& key, const UniqueId64x2& hashed_key);
|
|
547
613
|
|
|
@@ -565,40 +631,29 @@ class ALIGN_AS(CACHE_LINE_SIZE) ClockCacheShard final : public CacheShardBase {
|
|
|
565
631
|
// SecondaryCache not yet supported
|
|
566
632
|
Status Insert(const Slice& key, const UniqueId64x2& hashed_key, void* value,
|
|
567
633
|
const Cache::CacheItemHelper* helper, size_t charge,
|
|
568
|
-
|
|
634
|
+
HandleImpl** handle, Cache::Priority priority) {
|
|
569
635
|
return Insert(key, hashed_key, value, charge, helper->del_cb, handle,
|
|
570
636
|
priority);
|
|
571
637
|
}
|
|
572
638
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
639
|
+
HandleImpl* Lookup(const Slice& key, const UniqueId64x2& hashed_key,
|
|
640
|
+
const Cache::CacheItemHelper* /*helper*/,
|
|
641
|
+
const Cache::CreateCallback& /*create_cb*/,
|
|
642
|
+
Cache::Priority /*priority*/, bool /*wait*/,
|
|
643
|
+
Statistics* /*stats*/) {
|
|
578
644
|
return Lookup(key, hashed_key);
|
|
579
645
|
}
|
|
580
646
|
|
|
581
|
-
bool IsReady(
|
|
647
|
+
bool IsReady(HandleImpl* /*handle*/) { return true; }
|
|
582
648
|
|
|
583
|
-
void Wait(
|
|
649
|
+
void Wait(HandleImpl* /*handle*/) {}
|
|
584
650
|
|
|
585
651
|
// Acquire/release N references
|
|
586
|
-
void TEST_RefN(
|
|
587
|
-
void TEST_ReleaseN(
|
|
588
|
-
|
|
589
|
-
private: // functions
|
|
590
|
-
friend class ClockCache;
|
|
591
|
-
friend class ClockCacheTest;
|
|
592
|
-
|
|
593
|
-
ClockHandle* DetachedInsert(const ClockHandleBasicData& h);
|
|
594
|
-
|
|
595
|
-
// Returns the number of bits used to hash an element in the hash
|
|
596
|
-
// table.
|
|
597
|
-
static int CalcHashBits(size_t capacity, size_t estimated_value_size,
|
|
598
|
-
CacheMetadataChargePolicy metadata_charge_policy);
|
|
652
|
+
void TEST_RefN(HandleImpl* handle, size_t n);
|
|
653
|
+
void TEST_ReleaseN(HandleImpl* handle, size_t n);
|
|
599
654
|
|
|
600
655
|
private: // data
|
|
601
|
-
|
|
656
|
+
Table table_;
|
|
602
657
|
|
|
603
658
|
// Maximum total charge of all elements stored in the table.
|
|
604
659
|
std::atomic<size_t> capacity_;
|
|
@@ -611,8 +666,10 @@ class HyperClockCache
|
|
|
611
666
|
#ifdef NDEBUG
|
|
612
667
|
final
|
|
613
668
|
#endif
|
|
614
|
-
: public ShardedCache<ClockCacheShard
|
|
669
|
+
: public ShardedCache<ClockCacheShard<HyperClockTable>> {
|
|
615
670
|
public:
|
|
671
|
+
using Shard = ClockCacheShard<HyperClockTable>;
|
|
672
|
+
|
|
616
673
|
HyperClockCache(size_t capacity, size_t estimated_value_size,
|
|
617
674
|
int num_shard_bits, bool strict_capacity_limit,
|
|
618
675
|
CacheMetadataChargePolicy metadata_charge_policy,
|
|
@@ -627,6 +684,6 @@ class HyperClockCache
|
|
|
627
684
|
DeleterFn GetDeleter(Handle* handle) const override;
|
|
628
685
|
}; // class HyperClockCache
|
|
629
686
|
|
|
630
|
-
} // namespace
|
|
687
|
+
} // namespace clock_cache
|
|
631
688
|
|
|
632
689
|
} // namespace ROCKSDB_NAMESPACE
|
|
@@ -506,10 +506,14 @@ TEST_F(FastLRUCacheTest, CalcHashBitsTest) {
|
|
|
506
506
|
|
|
507
507
|
} // namespace fast_lru_cache
|
|
508
508
|
|
|
509
|
-
namespace
|
|
509
|
+
namespace clock_cache {
|
|
510
510
|
|
|
511
511
|
class ClockCacheTest : public testing::Test {
|
|
512
512
|
public:
|
|
513
|
+
using Shard = HyperClockCache::Shard;
|
|
514
|
+
using Table = HyperClockTable;
|
|
515
|
+
using HandleImpl = Shard::HandleImpl;
|
|
516
|
+
|
|
513
517
|
ClockCacheTest() {}
|
|
514
518
|
~ClockCacheTest() override { DeleteShard(); }
|
|
515
519
|
|
|
@@ -523,10 +527,13 @@ class ClockCacheTest : public testing::Test {
|
|
|
523
527
|
|
|
524
528
|
void NewShard(size_t capacity, bool strict_capacity_limit = true) {
|
|
525
529
|
DeleteShard();
|
|
526
|
-
shard_ =
|
|
527
|
-
port::cacheline_aligned_alloc(sizeof(
|
|
528
|
-
|
|
529
|
-
|
|
530
|
+
shard_ =
|
|
531
|
+
reinterpret_cast<Shard*>(port::cacheline_aligned_alloc(sizeof(Shard)));
|
|
532
|
+
|
|
533
|
+
Table::Opts opts;
|
|
534
|
+
opts.estimated_value_size = 1;
|
|
535
|
+
new (shard_)
|
|
536
|
+
Shard(capacity, strict_capacity_limit, kDontChargeCacheMetadata, opts);
|
|
530
537
|
}
|
|
531
538
|
|
|
532
539
|
Status Insert(const UniqueId64x2& hashed_key,
|
|
@@ -580,7 +587,7 @@ class ClockCacheTest : public testing::Test {
|
|
|
580
587
|
return {(static_cast<uint64_t>(key) << 56) + 1234U, 5678U};
|
|
581
588
|
}
|
|
582
589
|
|
|
583
|
-
|
|
590
|
+
Shard* shard_ = nullptr;
|
|
584
591
|
};
|
|
585
592
|
|
|
586
593
|
TEST_F(ClockCacheTest, Misc) {
|
|
@@ -604,7 +611,8 @@ TEST_F(ClockCacheTest, Misc) {
|
|
|
604
611
|
}
|
|
605
612
|
|
|
606
613
|
TEST_F(ClockCacheTest, Limits) {
|
|
607
|
-
|
|
614
|
+
constexpr size_t kCapacity = 3;
|
|
615
|
+
NewShard(kCapacity, false /*strict_capacity_limit*/);
|
|
608
616
|
for (bool strict_capacity_limit : {false, true, false}) {
|
|
609
617
|
SCOPED_TRACE("strict_capacity_limit = " +
|
|
610
618
|
std::to_string(strict_capacity_limit));
|
|
@@ -628,7 +636,7 @@ TEST_F(ClockCacheTest, Limits) {
|
|
|
628
636
|
|
|
629
637
|
// Single entry fills capacity
|
|
630
638
|
{
|
|
631
|
-
|
|
639
|
+
HandleImpl* h;
|
|
632
640
|
ASSERT_OK(shard_->Insert(TestKey(hkey), hkey, nullptr /*value*/,
|
|
633
641
|
3 /*charge*/, nullptr /*deleter*/, &h,
|
|
634
642
|
Cache::Priority::LOW));
|
|
@@ -644,15 +652,17 @@ TEST_F(ClockCacheTest, Limits) {
|
|
|
644
652
|
shard_->Release(h, false /*useful*/, false /*erase_if_last_ref*/);
|
|
645
653
|
}
|
|
646
654
|
|
|
647
|
-
// Insert more than table size can handle
|
|
648
|
-
// entries
|
|
655
|
+
// Insert more than table size can handle to exceed occupancy limit.
|
|
656
|
+
// (Cleverly using mostly zero-charge entries, but some non-zero to
|
|
657
|
+
// verify usage tracking on detached entries.)
|
|
649
658
|
{
|
|
650
659
|
size_t n = shard_->GetTableAddressCount() + 1;
|
|
651
|
-
std::unique_ptr<
|
|
660
|
+
std::unique_ptr<HandleImpl* []> ha { new HandleImpl* [n] {} };
|
|
652
661
|
Status s;
|
|
653
662
|
for (size_t i = 0; i < n && s.ok(); ++i) {
|
|
654
663
|
hkey[1] = i;
|
|
655
|
-
s = shard_->Insert(TestKey(hkey), hkey, nullptr /*value*/,
|
|
664
|
+
s = shard_->Insert(TestKey(hkey), hkey, nullptr /*value*/,
|
|
665
|
+
(i + kCapacity < n) ? 0 : 1 /*charge*/,
|
|
656
666
|
nullptr /*deleter*/, &ha[i], Cache::Priority::LOW);
|
|
657
667
|
if (i == 0) {
|
|
658
668
|
EXPECT_OK(s);
|
|
@@ -798,7 +808,7 @@ void IncrementIntDeleter(const Slice& /*key*/, void* value) {
|
|
|
798
808
|
// Testing calls to CorrectNearOverflow in Release
|
|
799
809
|
TEST_F(ClockCacheTest, ClockCounterOverflowTest) {
|
|
800
810
|
NewShard(6, /*strict_capacity_limit*/ false);
|
|
801
|
-
|
|
811
|
+
HandleImpl* h;
|
|
802
812
|
int deleted = 0;
|
|
803
813
|
UniqueId64x2 hkey = TestHashedKey('x');
|
|
804
814
|
ASSERT_OK(shard_->Insert(TestKey(hkey), hkey, &deleted, 1,
|
|
@@ -840,18 +850,18 @@ TEST_F(ClockCacheTest, CollidingInsertEraseTest) {
|
|
|
840
850
|
Slice key2 = TestKey(hkey2);
|
|
841
851
|
UniqueId64x2 hkey3 = TestHashedKey('z');
|
|
842
852
|
Slice key3 = TestKey(hkey3);
|
|
843
|
-
|
|
853
|
+
HandleImpl* h1;
|
|
844
854
|
ASSERT_OK(shard_->Insert(key1, hkey1, &deleted, 1, IncrementIntDeleter, &h1,
|
|
845
855
|
Cache::Priority::HIGH));
|
|
846
|
-
|
|
856
|
+
HandleImpl* h2;
|
|
847
857
|
ASSERT_OK(shard_->Insert(key2, hkey2, &deleted, 1, IncrementIntDeleter, &h2,
|
|
848
858
|
Cache::Priority::HIGH));
|
|
849
|
-
|
|
859
|
+
HandleImpl* h3;
|
|
850
860
|
ASSERT_OK(shard_->Insert(key3, hkey3, &deleted, 1, IncrementIntDeleter, &h3,
|
|
851
861
|
Cache::Priority::HIGH));
|
|
852
862
|
|
|
853
863
|
// Can repeatedly lookup+release despite the hash collision
|
|
854
|
-
|
|
864
|
+
HandleImpl* tmp_h;
|
|
855
865
|
for (bool erase_if_last_ref : {true, false}) { // but not last ref
|
|
856
866
|
tmp_h = shard_->Lookup(key1, hkey1);
|
|
857
867
|
ASSERT_EQ(h1, tmp_h);
|
|
@@ -999,7 +1009,7 @@ TEST_F(ClockCacheTest, TableSizesTest) {
|
|
|
999
1009
|
}
|
|
1000
1010
|
}
|
|
1001
1011
|
|
|
1002
|
-
} // namespace
|
|
1012
|
+
} // namespace clock_cache
|
|
1003
1013
|
|
|
1004
1014
|
class TestSecondaryCache : public SecondaryCache {
|
|
1005
1015
|
public:
|
|
@@ -281,7 +281,8 @@ Status BuildTable(
|
|
|
281
281
|
meta->fd.file_size = file_size;
|
|
282
282
|
meta->marked_for_compaction = builder->NeedCompact();
|
|
283
283
|
assert(meta->fd.GetFileSize() > 0);
|
|
284
|
-
tp = builder
|
|
284
|
+
tp = builder
|
|
285
|
+
->GetTableProperties(); // refresh now that builder is finished
|
|
285
286
|
if (memtable_payload_bytes != nullptr &&
|
|
286
287
|
memtable_garbage_bytes != nullptr) {
|
|
287
288
|
const CompactionIterationStats& ci_stats = c_iter.iter_stats();
|