virtual int prev() = 0;
virtual std::string key() = 0;
virtual std::pair<std::string,std::string> raw_key() = 0;
+ virtual bool raw_key_is_prefixed(const std::string &prefix) = 0;
virtual bufferlist value() = 0;
virtual int status() = 0;
virtual ~WholeSpaceIteratorImpl() { }
bool valid() {
if (!generic_iter->valid())
return false;
- std::pair<std::string,std::string> raw_key = generic_iter->raw_key();
- return (raw_key.first.compare(0, prefix.length(), prefix) == 0);
+ return generic_iter->raw_key_is_prefixed(prefix);
}
int next() {
if (valid())
int KineticStore::split_key(string in_prefix, string *prefix, string *key)
{
- size_t prefix_len = in_prefix.find('\1');
+ size_t prefix_len = 0;
+ char* in_data = in.c_str();
+
+ // Find separator inside Slice
+ char* separator = (char*) memchr((void*)in_data, 1, in.size());
+ if (separator == NULL)
+ return -EINVAL;
+ prefix_len = size_t(separator - in_data);
if (prefix_len >= in_prefix.size())
return -EINVAL;
+ // Fetch prefix and/or key directly from Slice
if (prefix)
- *prefix = string(in_prefix, 0, prefix_len);
+ *prefix = string(in_data, 0, prefix_len);
if (key)
- *key= string(in_prefix, prefix_len + 1);
+ *key = string(separator+1, 0, in_prefix.size()-prefix_len-1);
return 0;
}
return make_pair(prefix, key);
}
+bool KineticStore::KineticWholeSpaceIteratorImpl::raw_key_is_prefixed(const string &prefix) {
+ // Look for "prefix\1" right in *keys_iter without making a copy
+ string key = *keys_iter;
+ if ((key.size() > prefix.length()) && (key[prefix.length()] == '\1')) {
+ return memcmp(key.c_str(), prefix.c_str(), prefix.length()) == 0;
+ } else {
+ return false;
+ }
+}
+
+
bufferlist KineticStore::KineticWholeSpaceIteratorImpl::value() {
dout(30) << "kinetic iterator value()" << dendl;
unique_ptr<kinetic::KineticRecord> record;
int prev();
string key();
pair<string,string> raw_key();
+ bool raw_key_is_prefixed(const string &prefix);
bufferlist value();
int status();
};
int LevelDBStore::split_key(leveldb::Slice in, string *prefix, string *key)
{
- string in_prefix = in.ToString();
- size_t prefix_len = in_prefix.find('\0');
- if (prefix_len >= in_prefix.size())
+ size_t prefix_len = 0;
+
+ // Find separator inside Slice
+ char* separator = (char*) memchr(in.data(), 0, in.size());
+ if (separator == NULL)
+ return -EINVAL;
+ prefix_len = size_t(separator - in.data());
+ if (prefix_len >= in.size())
return -EINVAL;
+ // Fetch prefix and/or key directly from Slice
if (prefix)
- *prefix = string(in_prefix, 0, prefix_len);
+ *prefix = string(in.data(), 0, prefix_len);
if (key)
- *key= string(in_prefix, prefix_len + 1);
+ *key = string(separator+1, 0, in.size()-prefix_len-1);
return 0;
}
split_key(dbiter->key(), &prefix, &key);
return make_pair(prefix, key);
}
+ bool raw_key_is_prefixed(const string &prefix) {
+ leveldb::Slice key = dbiter->key();
+ if ((key.size() > prefix.length()) && (key[prefix.length()] == '\0')) {
+ return memcmp(key.data(), prefix.c_str(), prefix.length()) == 0;
+ } else {
+ return false;
+ }
+ }
bufferlist value() {
return to_bufferlist(dbiter->value());
}
int RocksDBStore::split_key(rocksdb::Slice in, string *prefix, string *key)
{
- string in_prefix = in.ToString();
- size_t prefix_len = in_prefix.find('\0');
- if (prefix_len >= in_prefix.size())
+ size_t prefix_len = 0;
+
+ // Find separator inside Slice
+ char* separator = (char*) memchr(in.data(), 0, in.size());
+ if (separator == NULL)
+ return -EINVAL;
+ prefix_len = size_t(separator - in.data());
+ if (prefix_len >= in.size())
return -EINVAL;
+ // Fetch prefix and/or key directly from Slice
if (prefix)
- *prefix = string(in_prefix, 0, prefix_len);
+ *prefix = string(in.data(), 0, prefix_len);
if (key)
- *key= string(in_prefix, prefix_len + 1);
+ *key = string(separator+1, 0, in.size()-prefix_len-1);
return 0;
}
split_key(dbiter->key(), &prefix, &key);
return make_pair(prefix, key);
}
+
+bool RocksDBStore::RocksDBWholeSpaceIteratorImpl::raw_key_is_prefixed(const string &prefix) {
+ // Look for "prefix\0" right in rocksb::Slice
+ rocksdb::Slice key = dbiter->key();
+ if ((key.size() > prefix.length()) && (key[prefix.length()] == '\0')) {
+ return memcmp(key.data(), prefix.c_str(), prefix.length()) == 0;
+ } else {
+ return false;
+ }
+}
+
bufferlist RocksDBStore::RocksDBWholeSpaceIteratorImpl::value()
{
return to_bufferlist(dbiter->value());
int prev();
string key();
pair<string,string> raw_key();
+ bool raw_key_is_prefixed(const string &prefix);
bufferlist value();
int status();
};