C: add MultiGet support

main
Reed Allman 10 years ago
parent a187e66ad0
commit 211a195d41
  1. 64
      db/c.cc
  2. 53
      db/c_test.c
  3. 28
      include/rocksdb/c.h

@ -836,6 +836,69 @@ char* rocksdb_get_cf(
return result; return result;
} }
void rocksdb_multi_get(
rocksdb_t* db,
const rocksdb_readoptions_t* options,
size_t num_keys, const char* const* keys_list,
const size_t* keys_list_sizes,
char** values_list, size_t* values_list_sizes,
char** errs) {
std::vector<Slice> keys(num_keys);
for (size_t i = 0; i < num_keys; i++) {
keys[i] = Slice(keys_list[i], keys_list_sizes[i]);
}
std::vector<std::string> values(num_keys);
std::vector<Status> statuses = db->rep->MultiGet(options->rep, keys, &values);
for (size_t i = 0; i < num_keys; i++) {
if (statuses[i].ok()) {
values_list[i] = CopyString(values[i]);
values_list_sizes[i] = values[i].size();
errs[i] = nullptr;
} else {
values_list[i] = nullptr;
values_list_sizes[i] = 0;
if (!statuses[i].IsNotFound()) {
errs[i] = strdup(statuses[i].ToString().c_str());
} else {
errs[i] = nullptr;
}
}
}
}
void rocksdb_multi_get_cf(
rocksdb_t* db,
const rocksdb_readoptions_t* options,
const rocksdb_column_family_handle_t* const* column_families,
size_t num_keys, const char* const* keys_list,
const size_t* keys_list_sizes,
char** values_list, size_t* values_list_sizes,
char** errs) {
std::vector<Slice> keys(num_keys);
std::vector<ColumnFamilyHandle*> cfs(num_keys);
for (size_t i = 0; i < num_keys; i++) {
keys[i] = Slice(keys_list[i], keys_list_sizes[i]);
cfs[i] = column_families[i]->rep;
}
std::vector<std::string> values(num_keys);
std::vector<Status> statuses = db->rep->MultiGet(options->rep, cfs, keys, &values);
for (size_t i = 0; i < num_keys; i++) {
if (statuses[i].ok()) {
values_list[i] = CopyString(values[i]);
values_list_sizes[i] = values[i].size();
errs[i] = nullptr;
} else {
values_list[i] = nullptr;
values_list_sizes[i] = 0;
if (!statuses[i].IsNotFound()) {
errs[i] = strdup(statuses[i].ToString().c_str());
} else {
errs[i] = nullptr;
}
}
}
}
rocksdb_iterator_t* rocksdb_create_iterator( rocksdb_iterator_t* rocksdb_create_iterator(
rocksdb_t* db, rocksdb_t* db,
const rocksdb_readoptions_t* options) { const rocksdb_readoptions_t* options) {
@ -1766,7 +1829,6 @@ void rocksdb_options_set_fifo_compaction_options(
/* /*
TODO: TODO:
DB::OpenForReadOnly DB::OpenForReadOnly
DB::MultiGet
DB::KeyMayExist DB::KeyMayExist
DB::GetOptions DB::GetOptions
DB::GetSortedWalFiles DB::GetSortedWalFiles

@ -505,6 +505,33 @@ int main(int argc, char** argv) {
rocksdb_iter_destroy(iter); rocksdb_iter_destroy(iter);
} }
StartPhase("multiget");
{
const char* keys[3] = { "box", "foo", "notfound" };
const size_t keys_sizes[3] = { 3, 3, 8 };
char* vals[3];
size_t vals_sizes[3];
char* errs[3];
rocksdb_multi_get(db, roptions, 3, keys, keys_sizes, vals, vals_sizes, errs);
int i;
for (i = 0; i < 3; i++) {
CheckEqual(NULL, errs[i], 0);
switch (i) {
case 0:
CheckEqual("c", vals[i], vals_sizes[i]);
break;
case 1:
CheckEqual("hello", vals[i], vals_sizes[i]);
break;
case 2:
CheckEqual(NULL, vals[i], vals_sizes[i]);
break;
}
Free(&vals[i]);
}
}
StartPhase("approximate_sizes"); StartPhase("approximate_sizes");
{ {
int i; int i;
@ -778,12 +805,36 @@ int main(int argc, char** argv) {
CheckGetCF(db, roptions, handles[1], "box", "c"); CheckGetCF(db, roptions, handles[1], "box", "c");
rocksdb_writebatch_destroy(wb); rocksdb_writebatch_destroy(wb);
const char* keys[3] = { "box", "box", "bar" };
const rocksdb_column_family_handle_t* get_handles[3] = { handles[0], handles[1], handles[1] };
const size_t keys_sizes[3] = { 3, 3, 8 };
char* vals[3];
size_t vals_sizes[3];
char* errs[3];
rocksdb_multi_get_cf(db, roptions, get_handles, 3, keys, keys_sizes, vals, vals_sizes, errs);
int i;
for (i = 0; i < 3; i++) {
CheckEqual(NULL, errs[i], 0);
switch (i) {
case 0:
CheckEqual(NULL, vals[i], vals_sizes[i]); // wrong cf
break;
case 1:
CheckEqual("c", vals[i], vals_sizes[i]); // bingo
break;
case 2:
CheckEqual(NULL, vals[i], vals_sizes[i]); // normal not found
break;
}
Free(&vals[i]);
}
rocksdb_iterator_t* iter = rocksdb_create_iterator_cf(db, roptions, handles[1]); rocksdb_iterator_t* iter = rocksdb_create_iterator_cf(db, roptions, handles[1]);
CheckCondition(!rocksdb_iter_valid(iter)); CheckCondition(!rocksdb_iter_valid(iter));
rocksdb_iter_seek_to_first(iter); rocksdb_iter_seek_to_first(iter);
CheckCondition(rocksdb_iter_valid(iter)); CheckCondition(rocksdb_iter_valid(iter));
int i;
for (i = 0; rocksdb_iter_valid(iter) != 0; rocksdb_iter_next(iter)) { for (i = 0; rocksdb_iter_valid(iter) != 0; rocksdb_iter_next(iter)) {
i++; i++;
} }

@ -264,6 +264,34 @@ extern char* rocksdb_get_cf(
size_t* vallen, size_t* vallen,
char** errptr); char** errptr);
// if values_list[i] == NULL and errs[i] == NULL,
// then we got status.IsNotFound(), which we will not return.
// all errors except status status.ok() and status.IsNotFound() are returned.
//
// errs, values_list and values_list_sizes must be num_keys in length,
// allocated by the caller.
// errs is a list of strings as opposed to the conventional one error,
// where errs[i] is the status for retrieval of keys_list[i].
// each non-NULL errs entry is a malloc()ed, null terminated string.
// each non-NULL values_list entry is a malloc()ed array, with
// the length for each stored in values_list_sizes[i].
extern void rocksdb_multi_get(
rocksdb_t* db,
const rocksdb_readoptions_t* options,
size_t num_keys, const char* const* keys_list,
const size_t* keys_list_sizes,
char** values_list, size_t* values_list_sizes,
char** errs);
extern void rocksdb_multi_get_cf(
rocksdb_t* db,
const rocksdb_readoptions_t* options,
const rocksdb_column_family_handle_t* const* column_families,
size_t num_keys, const char* const* keys_list,
const size_t* keys_list_sizes,
char** values_list, size_t* values_list_sizes,
char** errs);
extern rocksdb_iterator_t* rocksdb_create_iterator( extern rocksdb_iterator_t* rocksdb_create_iterator(
rocksdb_t* db, rocksdb_t* db,
const rocksdb_readoptions_t* options); const rocksdb_readoptions_t* options);

Loading…
Cancel
Save