rocksdb::Status Sortedint::RangeByValue()

in src/types/redis_sortedint.cc [156:206]


rocksdb::Status Sortedint::RangeByValue(engine::Context &ctx, const Slice &user_key, SortedintRangeSpec spec,
                                        std::vector<uint64_t> *ids, int *size) {
  if (size) *size = 0;
  if (ids) ids->clear();

  std::string ns_key = AppendNamespacePrefix(user_key);

  SortedintMetadata metadata(false);
  rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata);
  if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;

  std::string start_buf;
  PutFixed64(&start_buf, spec.reversed ? spec.max : spec.min);
  std::string start_key = InternalKey(ns_key, start_buf, metadata.version, storage_->IsSlotIdEncoded()).Encode();
  std::string prefix_key = InternalKey(ns_key, "", metadata.version, storage_->IsSlotIdEncoded()).Encode();
  std::string next_version_prefix_key =
      InternalKey(ns_key, "", metadata.version + 1, storage_->IsSlotIdEncoded()).Encode();

  rocksdb::ReadOptions read_options = ctx.DefaultScanOptions();
  rocksdb::Slice upper_bound(next_version_prefix_key);
  read_options.iterate_upper_bound = &upper_bound;
  rocksdb::Slice lower_bound(prefix_key);
  read_options.iterate_lower_bound = &lower_bound;

  int pos = 0;
  auto iter = util::UniqueIterator(ctx, read_options);
  if (!spec.reversed) {
    iter->Seek(start_key);
  } else {
    iter->SeekForPrev(start_key);
  }

  uint64_t id = 0;
  for (; iter->Valid() && iter->key().starts_with(prefix_key); !spec.reversed ? iter->Next() : iter->Prev()) {
    InternalKey ikey(iter->key(), storage_->IsSlotIdEncoded());
    Slice sub_key = ikey.GetSubKey();
    GetFixed64(&sub_key, &id);
    if (spec.reversed) {
      if ((spec.minex && id == spec.min) || id < spec.min) break;
      if ((spec.maxex && id == spec.max) || id > spec.max) continue;
    } else {
      if ((spec.minex && id == spec.min) || id < spec.min) continue;
      if ((spec.maxex && id == spec.max) || id > spec.max) break;
    }
    if (spec.offset >= 0 && pos++ < spec.offset) continue;
    if (ids) ids->emplace_back(id);
    if (size) *size += 1;
    if (spec.count > 0 && ids && ids->size() >= static_cast<unsigned>(spec.count)) break;
  }
  return rocksdb::Status::OK();
}