2cbb61eadb
Summary: clang-analyzer has uncovered a bunch of places where the code is relying on pointers being valid and one case (in VectorIterator) where a moved-from object is being used: In file included from db/range_tombstone_fragmenter.cc:17: ./util/vector_iterator.h:23:18: warning: Method called on moved-from object 'keys' of type 'std::vector' current_(keys.size()) { ^~~~~~~~~~~ 1 warning generated. utilities/persistent_cache/block_cache_tier_file.cc:39:14: warning: Called C++ object pointer is null Status s = env->NewRandomAccessFile(filepath, file, opt); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ utilities/persistent_cache/block_cache_tier_file.cc:47:19: warning: Called C++ object pointer is null Status status = env_->GetFileSize(Path(), size); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ utilities/persistent_cache/block_cache_tier_file.cc:290:14: warning: Called C++ object pointer is null Status s = env_->FileExists(Path()); ^~~~~~~~~~~~~~~~~~~~~~~~ utilities/persistent_cache/block_cache_tier_file.cc:363:35: warning: Called C++ object pointer is null CacheWriteBuffer* const buf = alloc_->Allocate(); ^~~~~~~~~~~~~~~~~~ utilities/persistent_cache/block_cache_tier_file.cc:399:41: warning: Called C++ object pointer is null const uint64_t file_off = buf_doff_ * alloc_->BufferSize(); ^~~~~~~~~~~~~~~~~~~~ utilities/persistent_cache/block_cache_tier_file.cc:463:33: warning: Called C++ object pointer is null size_t start_idx = lba.off_ / alloc_->BufferSize(); ^~~~~~~~~~~~~~~~~~~~ utilities/persistent_cache/block_cache_tier_file.cc:515:5: warning: Called C++ object pointer is null alloc_->Deallocate(bufs_[i]); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 warnings generated. ar: creating librocksdb_debug.a utilities/memory/memory_test.cc:68:25: warning: Called C++ object pointer is null cache_set->insert(db->GetDBOptions().row_cache.get()); ^~~~~~~~~~~~~~~~~~ 1 warning generated. The patch fixes these by adding assertions and explicitly passing in zero when initializing VectorIterator::current_ (which preserves the existing behavior). Pull Request resolved: https://github.com/facebook/rocksdb/pull/5821 Test Plan: Ran make check and make analyze to make sure the warnings have disappeared. Differential Revision: D17455949 Pulled By: ltamasi fbshipit-source-id: 363619618ea649a0674287f9f3b3393e390571ee
102 lines
2.8 KiB
C++
102 lines
2.8 KiB
C++
// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
|
#pragma once
|
|
|
|
#include <algorithm>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "db/dbformat.h"
|
|
#include "rocksdb/iterator.h"
|
|
#include "rocksdb/slice.h"
|
|
#include "table/internal_iterator.h"
|
|
|
|
namespace rocksdb {
|
|
|
|
// Iterator over a vector of keys/values
|
|
class VectorIterator : public InternalIterator {
|
|
public:
|
|
VectorIterator(std::vector<std::string> keys, std::vector<std::string> values,
|
|
const InternalKeyComparator* icmp)
|
|
: keys_(std::move(keys)),
|
|
values_(std::move(values)),
|
|
indexed_cmp_(icmp, &keys_),
|
|
current_(0) {
|
|
assert(keys_.size() == values_.size());
|
|
|
|
indices_.reserve(keys_.size());
|
|
for (size_t i = 0; i < keys_.size(); i++) {
|
|
indices_.push_back(i);
|
|
}
|
|
std::sort(indices_.begin(), indices_.end(), indexed_cmp_);
|
|
}
|
|
|
|
virtual bool Valid() const override {
|
|
return !indices_.empty() && current_ < indices_.size();
|
|
}
|
|
|
|
virtual void SeekToFirst() override { current_ = 0; }
|
|
virtual void SeekToLast() override { current_ = indices_.size() - 1; }
|
|
|
|
virtual void Seek(const Slice& target) override {
|
|
current_ = std::lower_bound(indices_.begin(), indices_.end(), target,
|
|
indexed_cmp_) -
|
|
indices_.begin();
|
|
}
|
|
|
|
virtual void SeekForPrev(const Slice& target) override {
|
|
current_ = std::lower_bound(indices_.begin(), indices_.end(), target,
|
|
indexed_cmp_) -
|
|
indices_.begin();
|
|
if (!Valid()) {
|
|
SeekToLast();
|
|
} else {
|
|
Prev();
|
|
}
|
|
}
|
|
|
|
virtual void Next() override { current_++; }
|
|
virtual void Prev() override { current_--; }
|
|
|
|
virtual Slice key() const override {
|
|
return Slice(keys_[indices_[current_]]);
|
|
}
|
|
virtual Slice value() const override {
|
|
return Slice(values_[indices_[current_]]);
|
|
}
|
|
|
|
virtual Status status() const override { return Status::OK(); }
|
|
|
|
virtual bool IsKeyPinned() const override { return true; }
|
|
virtual bool IsValuePinned() const override { return true; }
|
|
|
|
private:
|
|
struct IndexedKeyComparator {
|
|
IndexedKeyComparator(const InternalKeyComparator* c,
|
|
const std::vector<std::string>* ks)
|
|
: cmp(c), keys(ks) {}
|
|
|
|
bool operator()(size_t a, size_t b) const {
|
|
return cmp->Compare((*keys)[a], (*keys)[b]) < 0;
|
|
}
|
|
|
|
bool operator()(size_t a, const Slice& b) const {
|
|
return cmp->Compare((*keys)[a], b) < 0;
|
|
}
|
|
|
|
bool operator()(const Slice& a, size_t b) const {
|
|
return cmp->Compare(a, (*keys)[b]) < 0;
|
|
}
|
|
|
|
const InternalKeyComparator* cmp;
|
|
const std::vector<std::string>* keys;
|
|
};
|
|
|
|
std::vector<std::string> keys_;
|
|
std::vector<std::string> values_;
|
|
IndexedKeyComparator indexed_cmp_;
|
|
std::vector<size_t> indices_;
|
|
size_t current_;
|
|
};
|
|
|
|
} // namespace rocksdb
|