diff --git a/sstables/generation_type.hh b/sstables/generation_type.hh index f43ebf74bd..47517aca8a 100644 --- a/sstables/generation_type.hh +++ b/sstables/generation_type.hh @@ -13,7 +13,9 @@ #include #include #include +#include #include +#include #include namespace sstables { @@ -56,6 +58,35 @@ Target generations_from_values(std::initializer_list val })); } +class sstable_generation_generator { + // We still want to do our best to keep the generation numbers shard-friendly. + // Each destination shard will manage its own generation counter. + // + // operator() is called by multiple shards in parallel when performing reshard, + // so we have to use atomic<> here. + using int_t = sstables::generation_type::int_t; + int_t _last_generation; + static int_t base_generation(int_t highest_generation) { + // get the base generation so we can increment it by smp::count without + // conflicting with other shards + return highest_generation - highest_generation % seastar::smp::count + seastar::this_shard_id(); + } +public: + explicit sstable_generation_generator(int64_t last_generation) + : _last_generation(base_generation(last_generation)) {} + void update_known_generation(int64_t generation) { + if (generation > _last_generation) { + _last_generation = generation; + } + } + sstables::generation_type operator()() { + // each shard has its own "namespace" so we increment the generation id + // by smp::count to avoid name confliction of sstables + _last_generation += seastar::smp::count; + return sstables::generation_from_value(_last_generation); + } +}; + } //namespace sstables namespace std {