ribbon_config.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright (c) Facebook, Inc. and its affiliates. 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. #pragma once
  6. #include <array>
  7. #include <cassert>
  8. #include <cmath>
  9. #include <cstdint>
  10. #include "port/lang.h" // for FALLTHROUGH_INTENDED
  11. #include "rocksdb/rocksdb_namespace.h"
  12. namespace ROCKSDB_NAMESPACE {
  13. namespace ribbon {
  14. // RIBBON PHSF & RIBBON Filter (Rapid Incremental Boolean Banding ON-the-fly)
  15. //
  16. // ribbon_config.h: APIs for relating numbers of slots with numbers of
  17. // additions for tolerable construction failure probabilities. This is
  18. // separate from ribbon_impl.h because it might not be needed for
  19. // some applications.
  20. //
  21. // This API assumes uint32_t for number of slots, as a single Ribbon
  22. // linear system should not normally overflow that without big penalties.
  23. //
  24. // Template parameter kCoeffBits uses uint64_t for convenience in case it
  25. // comes from size_t.
  26. //
  27. // Most of the complexity here is trying to optimize speed and
  28. // compiled code size, using templates to minimize table look-ups and
  29. // the compiled size of all linked look-up tables. Look-up tables are
  30. // required because we don't have good formulas, and the data comes
  31. // from running FindOccupancy in ribbon_test.
  32. // Represents a chosen chance of successful Ribbon construction for a single
  33. // seed. Allowing higher chance of failed construction can reduce space
  34. // overhead but takes extra time in construction.
  35. enum ConstructionFailureChance {
  36. kOneIn2,
  37. kOneIn20,
  38. // When using kHomogeneous==true, construction failure chance should
  39. // not generally exceed target FP rate, so it unlikely useful to
  40. // allow a higher "failure" chance. In some cases, even more overhead
  41. // is appropriate. (TODO)
  42. kOneIn1000,
  43. };
  44. namespace detail {
  45. // It is useful to compile ribbon_test linking to BandingConfigHelper with
  46. // settings for which we do not have configuration data, as long as we don't
  47. // run the code. This template hack supports that.
  48. template <ConstructionFailureChance kCfc, uint64_t kCoeffBits, bool kUseSmash,
  49. bool kHomogeneous, bool kIsSupported>
  50. struct BandingConfigHelper1MaybeSupported {
  51. public:
  52. static uint32_t GetNumToAdd(uint32_t num_slots) {
  53. // Unsupported
  54. assert(num_slots == 0);
  55. (void)num_slots;
  56. return 0;
  57. }
  58. static uint32_t GetNumSlots(uint32_t num_to_add) {
  59. // Unsupported
  60. assert(num_to_add == 0);
  61. (void)num_to_add;
  62. return 0;
  63. }
  64. };
  65. // Base class for BandingConfigHelper1 and helper for BandingConfigHelper
  66. // with core implementations built on above data
  67. template <ConstructionFailureChance kCfc, uint64_t kCoeffBits, bool kUseSmash,
  68. bool kHomogeneous>
  69. struct BandingConfigHelper1MaybeSupported<
  70. kCfc, kCoeffBits, kUseSmash, kHomogeneous, true /* kIsSupported */> {
  71. public:
  72. // See BandingConfigHelper1. Implementation in ribbon_config.cc
  73. static uint32_t GetNumToAdd(uint32_t num_slots);
  74. // See BandingConfigHelper1. Implementation in ribbon_config.cc
  75. static uint32_t GetNumSlots(uint32_t num_to_add);
  76. };
  77. } // namespace detail
  78. template <ConstructionFailureChance kCfc, uint64_t kCoeffBits, bool kUseSmash,
  79. bool kHomogeneous>
  80. struct BandingConfigHelper1
  81. : public detail::BandingConfigHelper1MaybeSupported<
  82. kCfc, kCoeffBits, kUseSmash, kHomogeneous,
  83. /* kIsSupported */ kCoeffBits == 64 || kCoeffBits == 128> {
  84. public:
  85. // Returns a number of entries that can be added to a given number of
  86. // slots, with roughly kCfc chance of construction failure per seed,
  87. // or better. Does NOT do rounding for InterleavedSoln; call
  88. // RoundUpNumSlots for that.
  89. //
  90. // inherited:
  91. // static uint32_t GetNumToAdd(uint32_t num_slots);
  92. // Returns a number of slots for a given number of entries to add
  93. // that should have roughly kCfc chance of construction failure per
  94. // seed, or better. Does NOT do rounding for InterleavedSoln; call
  95. // RoundUpNumSlots for that.
  96. //
  97. // num_to_add should not exceed roughly 2/3rds of the maximum value
  98. // of the uint32_t type to avoid overflow.
  99. //
  100. // inherited:
  101. // static uint32_t GetNumSlots(uint32_t num_to_add);
  102. };
  103. // Configured using TypesAndSettings as in ribbon_impl.h
  104. template <ConstructionFailureChance kCfc, class TypesAndSettings>
  105. struct BandingConfigHelper1TS
  106. : public BandingConfigHelper1<
  107. kCfc,
  108. /* kCoeffBits */ sizeof(typename TypesAndSettings::CoeffRow) * 8U,
  109. TypesAndSettings::kUseSmash, TypesAndSettings::kHomogeneous> {};
  110. // Like BandingConfigHelper1TS except failure chance can be a runtime rather
  111. // than compile time value.
  112. template <class TypesAndSettings>
  113. struct BandingConfigHelper {
  114. public:
  115. static constexpr ConstructionFailureChance kDefaultFailureChance =
  116. TypesAndSettings::kHomogeneous ? kOneIn1000 : kOneIn20;
  117. static uint32_t GetNumToAdd(
  118. uint32_t num_slots,
  119. ConstructionFailureChance max_failure = kDefaultFailureChance) {
  120. switch (max_failure) {
  121. default:
  122. assert(false);
  123. FALLTHROUGH_INTENDED;
  124. case kOneIn20: {
  125. using H1 = BandingConfigHelper1TS<kOneIn20, TypesAndSettings>;
  126. return H1::GetNumToAdd(num_slots);
  127. }
  128. case kOneIn2: {
  129. using H1 = BandingConfigHelper1TS<kOneIn2, TypesAndSettings>;
  130. return H1::GetNumToAdd(num_slots);
  131. }
  132. case kOneIn1000: {
  133. using H1 = BandingConfigHelper1TS<kOneIn1000, TypesAndSettings>;
  134. return H1::GetNumToAdd(num_slots);
  135. }
  136. }
  137. }
  138. static uint32_t GetNumSlots(
  139. uint32_t num_to_add,
  140. ConstructionFailureChance max_failure = kDefaultFailureChance) {
  141. switch (max_failure) {
  142. default:
  143. assert(false);
  144. FALLTHROUGH_INTENDED;
  145. case kOneIn20: {
  146. using H1 = BandingConfigHelper1TS<kOneIn20, TypesAndSettings>;
  147. return H1::GetNumSlots(num_to_add);
  148. }
  149. case kOneIn2: {
  150. using H1 = BandingConfigHelper1TS<kOneIn2, TypesAndSettings>;
  151. return H1::GetNumSlots(num_to_add);
  152. }
  153. case kOneIn1000: {
  154. using H1 = BandingConfigHelper1TS<kOneIn1000, TypesAndSettings>;
  155. return H1::GetNumSlots(num_to_add);
  156. }
  157. }
  158. }
  159. };
  160. } // namespace ribbon
  161. } // namespace ROCKSDB_NAMESPACE