C: add MultiGet support
This commit is contained in:
parent
a187e66ad0
commit
211a195d41
64
db/c.cc
64
db/c.cc
@ -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
|
||||||
|
53
db/c_test.c
53
db/c_test.c
@ -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…
Reference in New Issue
Block a user