diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1204157..4b643dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,12 +9,31 @@ on: name: CI jobs: - build: - name: build + check: + name: check runs-on: ubuntu-latest + env: + CARGO_TARGET_DIR: "./build" steps: - - uses: actions/checkout@v2 - - name: Rust Cache - uses: Swatinem/rust-cache@v1.4.0 + - uses: actions/checkout@v3 + - name: cpp lint + uses: DoozyX/clang-format-lint-action@v0.16.2 + with: + source: '.' + extensions: 'cpp,h' + exclude: 'build' + style: Google + - name: rust cache + uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + build/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + - name: rust lint + run: cargo fmt -- --check && cargo clippy -- -D warnings && cargo check --all-targets --all-features - name: cmake build - run: cmake -S . -B build && cmake --build build + run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug && cmake --build build diff --git a/example/raw.cpp b/example/raw.cpp index db51b1a..7fa96d6 100644 --- a/example/raw.cpp +++ b/example/raw.cpp @@ -1,40 +1,42 @@ // Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0. -#include #include +#include + int main() { - auto client = tikv_client::RawKVClient({"127.0.0.1:2379"}); - - const std::uint32_t kTimeoutMs = 10; - client.put("k1", "v1", kTimeoutMs); - - auto val = client.get("k1",kTimeoutMs); - if (val) { - std::cout << "get key: \n(k1:" << *val << ")" << std::endl; - } else { - std::cout << "key not found" << std::endl; - } - - client.batch_put({{"k2","v2"},{"k3","v3"},{"k4","v4"},{"k5","v5"}}, kTimeoutMs); - - const std::uint32_t kLimit = 20; - // scan [k1,k6), limit 20, timeout 10ms - auto kv_pairs = client.scan("k1","k6", kLimit ,kTimeoutMs); - std::cout<<"scan[\"k1\",\"k6\"):"<key << ": " << iter->value << ") "; - } - std::cout << std::endl; - - // delete [k3,k5), so [k1,k6) should be [k1,k3) + [k5,k6) - std::cout<<"scan[\"k1\",\"k6\") after delete:"<key << ": " << iter->value << ") "; - } - std::cout << std::endl; - - return 0; + auto client = tikv_client::RawKVClient({"127.0.0.1:2379"}); + + const std::uint32_t kTimeoutMs = 10; + client.put("k1", "v1", kTimeoutMs); + + auto val = client.get("k1", kTimeoutMs); + if (val) { + std::cout << "get key: \n(k1:" << *val << ")" << std::endl; + } else { + std::cout << "key not found" << std::endl; + } + + client.batch_put({{"k2", "v2"}, {"k3", "v3"}, {"k4", "v4"}, {"k5", "v5"}}, + kTimeoutMs); + + const std::uint32_t kLimit = 20; + // scan [k1,k6), limit 20, timeout 10ms + auto kv_pairs = client.scan("k1", "k6", kLimit, kTimeoutMs); + std::cout << "scan[\"k1\",\"k6\"):" << std::endl; + for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { + std::cout << "(" << iter->key << ": " << iter->value << ") "; + } + std::cout << std::endl; + + // delete [k3,k5), so [k1,k6) should be [k1,k3) + [k5,k6) + std::cout << "scan[\"k1\",\"k6\") after delete:" << std::endl; + client.remove_range("k3", "k5", kTimeoutMs); + kv_pairs = client.scan("k1", "k6", kLimit, kTimeoutMs); + for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { + std::cout << "(" << iter->key << ": " << iter->value << ") "; + } + std::cout << std::endl; + + return 0; } diff --git a/example/txn.cpp b/example/txn.cpp index eca8420..aed323a 100644 --- a/example/txn.cpp +++ b/example/txn.cpp @@ -1,27 +1,28 @@ // Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0. -#include #include +#include + int main() { - auto client = tikv_client::TransactionClient({"127.0.0.1:2379"}); - auto txn = client.begin(); + auto client = tikv_client::TransactionClient({"127.0.0.1:2379"}); + auto txn = client.begin(); - txn.put("k1", "v2"); + txn.put("k1", "v2"); - auto val = txn.get("k1"); - if (val) { - std::cout << "get key k1:" << *val << std::endl; - } else { - std::cout << "key not found" << std::endl; - } + auto val = txn.get("k1"); + if (val) { + std::cout << "get key k1:" << *val << std::endl; + } else { + std::cout << "key not found" << std::endl; + } - auto kv_pairs = txn.scan("k1", Bound::Included, "", Bound::Unbounded, 10); - for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { - std::cout << "scan:" << iter->key << ": " << iter->value << std::endl; - } + auto kv_pairs = txn.scan("k1", Bound::Included, "", Bound::Unbounded, 10); + for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { + std::cout << "scan:" << iter->key << ": " << iter->value << std::endl; + } - txn.commit(); + txn.commit(); - return 0; + return 0; } diff --git a/include/tikv_client.h b/include/tikv_client.h index 7f52684..903df36 100644 --- a/include/tikv_client.h +++ b/include/tikv_client.h @@ -1,62 +1,75 @@ // Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0. #ifndef _TIKV_CLIENT_H_ -#define _TIKV_CLIENT_H_ +#define _TIKV_CLIENT_H_ -#include "lib.rs.h" #include #include +#include "lib.rs.h" + namespace tikv_client { struct KvPair final { - std::string key; - std::string value; + std::string key; + std::string value; - KvPair(std::string &&key, std::string &&value); - ffi::KvPair to_ffi(); + KvPair(std::string &&key, std::string &&value); + ffi::KvPair to_ffi(); }; class Transaction { -public: - Transaction(::rust::cxxbridge1::Box txn); - std::optional get(const std::string &key); - std::optional get_for_update(const std::string &key); - std::vector batch_get(const std::vector &keys); - std::vector batch_get_for_update(const std::vector &keys); - std::vector scan(const std::string &start, Bound start_bound, const std::string &end, Bound end_bound, std::uint32_t limit); - std::vector scan_keys(const std::string &start, Bound start_bound, const std::string &end, Bound end_bound, std::uint32_t limit); - void put(const std::string &key, const std::string &value); - void batch_put(const std::vector &kvs); - void remove(const std::string &key); - void commit(); -private: - ::rust::cxxbridge1::Box _txn; + public: + Transaction(::rust::cxxbridge1::Box txn); + std::optional get(const std::string &key); + std::optional get_for_update(const std::string &key); + std::vector batch_get(const std::vector &keys); + std::vector batch_get_for_update( + const std::vector &keys); + std::vector scan(const std::string &start, Bound start_bound, + const std::string &end, Bound end_bound, + std::uint32_t limit); + std::vector scan_keys(const std::string &start, + Bound start_bound, const std::string &end, + Bound end_bound, std::uint32_t limit); + void put(const std::string &key, const std::string &value); + void batch_put(const std::vector &kvs); + void remove(const std::string &key); + void commit(); + + private: + ::rust::cxxbridge1::Box _txn; }; class TransactionClient { -public: - TransactionClient(const std::vector &pd_endpoints); - Transaction begin(); - Transaction begin_pessimistic(); -private: - ::rust::cxxbridge1::Box _client; + public: + TransactionClient(const std::vector &pd_endpoints); + Transaction begin(); + Transaction begin_pessimistic(); + + private: + ::rust::cxxbridge1::Box _client; }; class RawKVClient { -public: - RawKVClient(const std::vector &pd_endpoints); - std::optional get(const std::string &key,const std::uint64_t timeout); - void put(const std::string &key, const std::string &value, const std::uint64_t timeout); - void batch_put(const std::vector &kvs, const std::uint64_t timeout); - void remove(const std::string &key, const std::uint64_t timeout); - void remove_range(const std::string &start_key, const std::string &end_key, const std::uint64_t timeout); - std::vector scan(const std::string &startKey, const std::string &endKey, std::uint32_t limit, const std::uint64_t timeout); - -private: - ::rust::cxxbridge1::Box _client; + public: + RawKVClient(const std::vector &pd_endpoints); + std::optional get(const std::string &key, + const std::uint64_t timeout); + void put(const std::string &key, const std::string &value, + const std::uint64_t timeout); + void batch_put(const std::vector &kvs, const std::uint64_t timeout); + void remove(const std::string &key, const std::uint64_t timeout); + void remove_range(const std::string &start_key, const std::string &end_key, + const std::uint64_t timeout); + std::vector scan(const std::string &startKey, + const std::string &endKey, std::uint32_t limit, + const std::uint64_t timeout); + + private: + ::rust::cxxbridge1::Box _client; }; -} // namespace tikv_client +} // namespace tikv_client -#endif //_TIKV_CLIENT_H_ +#endif //_TIKV_CLIENT_H_ diff --git a/src/tikv_client.cpp b/src/tikv_client.cpp index 4d4a49a..af64e5d 100644 --- a/src/tikv_client.cpp +++ b/src/tikv_client.cpp @@ -8,167 +8,178 @@ using ::rust::cxxbridge1::Box; namespace tikv_client { KvPair::KvPair(std::string &&key, std::string &&value) - : key(std::move(key)) - , value(std::move(value)) -{} + : key(std::move(key)), value(std::move(value)) {} ffi::KvPair KvPair::to_ffi() { - ffi::KvPair f_pair; - f_pair.key.reserve(key.size()); - for (const auto &c : this->key) { - f_pair.key.emplace_back(static_cast(c)); - } - f_pair.value.reserve(value.size()); - for (const auto &c : this->value) { - f_pair.value.emplace_back(static_cast(c)); - } - return f_pair; -} - -TransactionClient::TransactionClient(const std::vector &pd_endpoints): - _client(tikv_client_glue::transaction_client_new(pd_endpoints)) {} - -RawKVClient::RawKVClient(const std::vector &pd_endpoints): - _client(tikv_client_glue::raw_client_new(pd_endpoints)) {} - -std::optional RawKVClient::get(const std::string &key, const std::uint64_t timeout) { - auto val = tikv_client_glue::raw_get(*_client,key,timeout); - if (val.is_none) { - return std::nullopt; - } else { - return std::string{val.value.begin(), val.value.end()}; - } -} - -void RawKVClient::put(const std::string &key, const std::string &value, const std::uint64_t timeout) { - tikv_client_glue::raw_put(*_client,key,value,timeout); -} - -void RawKVClient::batch_put(const std::vector &kv_pairs, const std::uint64_t timeout) { - std::vector pairs; - pairs.reserve(kv_pairs.size()); - for (auto pair: kv_pairs) { - pairs.emplace_back(pair.to_ffi()); - } - tikv_client_glue::raw_batch_put(*_client,pairs,timeout); -} - -std::vector RawKVClient::scan(const std::string &startKey, const std::string &endKey, std::uint32_t limit, const std::uint64_t timeout){ - auto kv_pairs = tikv_client_glue::raw_scan(*_client,startKey,endKey,limit,timeout); - std::vector result; - result.reserve(kv_pairs.size()); - for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { - result.emplace_back( - std::string{(iter->key).begin(), (iter->key).end()}, - std::string{(iter->value).begin(), (iter->value).end()} - ); - } - return result; + ffi::KvPair f_pair; + f_pair.key.reserve(key.size()); + for (const auto &c : this->key) { + f_pair.key.emplace_back(static_cast(c)); + } + f_pair.value.reserve(value.size()); + for (const auto &c : this->value) { + f_pair.value.emplace_back(static_cast(c)); + } + return f_pair; +} + +TransactionClient::TransactionClient( + const std::vector &pd_endpoints) + : _client(tikv_client_glue::transaction_client_new(pd_endpoints)) {} + +RawKVClient::RawKVClient(const std::vector &pd_endpoints) + : _client(tikv_client_glue::raw_client_new(pd_endpoints)) {} + +std::optional RawKVClient::get(const std::string &key, + const std::uint64_t timeout) { + auto val = tikv_client_glue::raw_get(*_client, key, timeout); + if (val.is_none) { + return std::nullopt; + } else { + return std::string{val.value.begin(), val.value.end()}; + } +} + +void RawKVClient::put(const std::string &key, const std::string &value, + const std::uint64_t timeout) { + tikv_client_glue::raw_put(*_client, key, value, timeout); +} + +void RawKVClient::batch_put(const std::vector &kv_pairs, + const std::uint64_t timeout) { + std::vector pairs; + pairs.reserve(kv_pairs.size()); + for (auto pair : kv_pairs) { + pairs.emplace_back(pair.to_ffi()); + } + tikv_client_glue::raw_batch_put(*_client, pairs, timeout); +} + +std::vector RawKVClient::scan(const std::string &startKey, + const std::string &endKey, + std::uint32_t limit, + const std::uint64_t timeout) { + auto kv_pairs = + tikv_client_glue::raw_scan(*_client, startKey, endKey, limit, timeout); + std::vector result; + result.reserve(kv_pairs.size()); + for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { + result.emplace_back( + std::string{(iter->key).begin(), (iter->key).end()}, + std::string{(iter->value).begin(), (iter->value).end()}); + } + return result; } void RawKVClient::remove(const std::string &key, const std::uint64_t timeout) { - tikv_client_glue::raw_delete(*_client,key,timeout); + tikv_client_glue::raw_delete(*_client, key, timeout); } -void RawKVClient::remove_range(const std::string &start_key,const std::string &end_key, const std::uint64_t timeout) { - tikv_client_glue::raw_delete_range(*_client,start_key,end_key,timeout); +void RawKVClient::remove_range(const std::string &start_key, + const std::string &end_key, + const std::uint64_t timeout) { + tikv_client_glue::raw_delete_range(*_client, start_key, end_key, timeout); } Transaction TransactionClient::begin() { - return Transaction(transaction_client_begin(*_client)); + return Transaction(transaction_client_begin(*_client)); } Transaction TransactionClient::begin_pessimistic() { - return Transaction(transaction_client_begin_pessimistic(*_client)); + return Transaction(transaction_client_begin_pessimistic(*_client)); } - -Transaction::Transaction(Box txn) : _txn(std::move(txn)) {} +Transaction::Transaction(Box txn) + : _txn(std::move(txn)) {} std::optional Transaction::get(const std::string &key) { - auto val = transaction_get(*_txn, key); - if (val.is_none) { - return std::nullopt; - } else { - return std::string{val.value.begin(), val.value.end()}; - } + auto val = transaction_get(*_txn, key); + if (val.is_none) { + return std::nullopt; + } else { + return std::string{val.value.begin(), val.value.end()}; + } } std::optional Transaction::get_for_update(const std::string &key) { - auto val = transaction_get_for_update(*_txn, key); - if (val.is_none) { - return std::nullopt; - } else { - return std::string{val.value.begin(), val.value.end()}; - } -} - -std::vector Transaction::batch_get(const std::vector &keys) { - auto kv_pairs = transaction_batch_get(*_txn, keys); - std::vector result; - result.reserve(kv_pairs.size()); - for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { - result.emplace_back( - std::string{(iter->key).begin(), (iter->key).end()}, - std::string{(iter->value).begin(), (iter->value).end()} - ); - } - return result; -} - -std::vector Transaction::batch_get_for_update(const std::vector &keys) { - auto kv_pairs = transaction_batch_get_for_update(*_txn, keys); - std::vector result; - result.reserve(kv_pairs.size()); - for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { - result.emplace_back( - std::string{(iter->key).begin(), (iter->key).end()}, - std::string{(iter->value).begin(), (iter->value).end()} - ); - } - return result; -} - - -std::vector Transaction::scan(const std::string &start, Bound start_bound, const std::string &end, Bound end_bound, std::uint32_t limit) { - auto kv_pairs = transaction_scan(*_txn, start, start_bound, end, end_bound, limit); - std::vector result; - result.reserve(kv_pairs.size()); - for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { - result.emplace_back( - std::string{(iter->key).begin(), (iter->key).end()}, - std::string{(iter->value).begin(), (iter->value).end()} - ); - } - return result; -} - -std::vector Transaction::scan_keys(const std::string &start, Bound start_bound, const std::string &end, Bound end_bound, std::uint32_t limit) { - auto keys = transaction_scan_keys(*_txn, start, start_bound, end, end_bound, limit); - std::vector result; - result.reserve(keys.size()); - for (auto iter = keys.begin(); iter != keys.end(); ++iter) { - result.emplace_back(std::string{(iter->key).begin(), (iter->key).end()}); - } - return result; + auto val = transaction_get_for_update(*_txn, key); + if (val.is_none) { + return std::nullopt; + } else { + return std::string{val.value.begin(), val.value.end()}; + } +} + +std::vector Transaction::batch_get( + const std::vector &keys) { + auto kv_pairs = transaction_batch_get(*_txn, keys); + std::vector result; + result.reserve(kv_pairs.size()); + for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { + result.emplace_back( + std::string{(iter->key).begin(), (iter->key).end()}, + std::string{(iter->value).begin(), (iter->value).end()}); + } + return result; +} + +std::vector Transaction::batch_get_for_update( + const std::vector &keys) { + auto kv_pairs = transaction_batch_get_for_update(*_txn, keys); + std::vector result; + result.reserve(kv_pairs.size()); + for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { + result.emplace_back( + std::string{(iter->key).begin(), (iter->key).end()}, + std::string{(iter->value).begin(), (iter->value).end()}); + } + return result; +} + +std::vector Transaction::scan(const std::string &start, + Bound start_bound, const std::string &end, + Bound end_bound, std::uint32_t limit) { + auto kv_pairs = + transaction_scan(*_txn, start, start_bound, end, end_bound, limit); + std::vector result; + result.reserve(kv_pairs.size()); + for (auto iter = kv_pairs.begin(); iter != kv_pairs.end(); ++iter) { + result.emplace_back( + std::string{(iter->key).begin(), (iter->key).end()}, + std::string{(iter->value).begin(), (iter->value).end()}); + } + return result; +} + +std::vector Transaction::scan_keys(const std::string &start, + Bound start_bound, + const std::string &end, + Bound end_bound, + std::uint32_t limit) { + auto keys = + transaction_scan_keys(*_txn, start, start_bound, end, end_bound, limit); + std::vector result; + result.reserve(keys.size()); + for (auto iter = keys.begin(); iter != keys.end(); ++iter) { + result.emplace_back(std::string{(iter->key).begin(), (iter->key).end()}); + } + return result; } void Transaction::put(const std::string &key, const std::string &value) { - transaction_put(*_txn, key, value); + transaction_put(*_txn, key, value); } void Transaction::batch_put(const std::vector &kvs) { - for (auto iter = kvs.begin(); iter != kvs.end(); ++iter) { - transaction_put(*_txn, iter->key, iter->value); - } + for (auto iter = kvs.begin(); iter != kvs.end(); ++iter) { + transaction_put(*_txn, iter->key, iter->value); + } } void Transaction::remove(const std::string &key) { - transaction_delete(*_txn, key); + transaction_delete(*_txn, key); } -void Transaction::commit() { - transaction_commit(*_txn); -} +void Transaction::commit() { transaction_commit(*_txn); } -} +} // namespace tikv_client