Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions example/cpp-exchange/in-mem/proof_of_concept_iface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ class UnorderedMapClient : public radex::IClient {
return true;
}

private:
void delete_key(std::string_view key) override {
_map.erase(std::string{key});
}

public:
void put_bytes(std::string_view key, const void *bytes,
radex::detail::MetaInt length) override {
auto ptr = static_cast<const std::uint8_t *>(bytes);
Expand Down
11 changes: 11 additions & 0 deletions include/radex/client_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ class IClient {
// <<< End Virtual Methods <<<

private:
/// Delete the entry stored under `key` in the backing store.
virtual void delete_key(std::string_view key) = 0;

detail::ItemInfo get_item_info(
std::function<detail::BytesBuffer(std::string_view)> fetch_bytes,
const data::IncomingHandle &handle);
Expand All @@ -213,6 +216,9 @@ class IClient {
wait_for_item_info_ptr(const data::IncomingHandle &handle,
std::chrono::milliseconds timeout);

/// Delete a typed value and its associated metadata.
void delete_item(const data::OutgoingHandle &handle);

public:
/// Store a scalar value under `handle`.
/// @tparam T One of `int32_t`, `int64_t`, `float`, `double`.
Expand Down Expand Up @@ -363,6 +369,11 @@ class Client : public IClient {
throw_backend_unavailable();
}

private:
void delete_key(std::string_view key) override {
throw_backend_unavailable();
}

void put_bytes(std::string_view key, const void *bytes, detail::MetaInt length) override {
throw_backend_unavailable();
}
Expand Down
2 changes: 2 additions & 0 deletions include/radex/dragon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class Client : public IClient {

Client(dragon::DDict<dragon::Serializable, dragon::Serializable> ddict);

void delete_key(std::string_view key) override;

bool dormant_timeout_warning_triggered = false;

public:
Expand Down
2 changes: 2 additions & 0 deletions include/radex/smartredis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class Client : public IClient {
Client(std::unique_ptr<SmartRedis::ConfigOptions> options,
std::string_view logger_name);

void delete_key(std::string_view key) override;

public:
/// Connect using configuration read from the environment.
Client();
Expand Down
7 changes: 7 additions & 0 deletions src/cpp/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ IClient::wait_for_item_info_ptr(const data::IncomingHandle &handle,
get_item_info(fetch_bytes, handle));
}

void IClient::delete_item(const data::OutgoingHandle &handle) {
delete_key(handle.key());
if (contains(handle.metadata_key())) {
delete_key(handle.metadata_key());
}
}

detail::MetaData IClient::get_meta_data(const data::IncomingHandle &handle) {
return detail::MetaData::from_buffer(get_bytes(handle.metadata_key()));
}
Expand Down
5 changes: 5 additions & 0 deletions src/cpp/dragon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ bool Client::contains(std::string_view key) {
return ddict.contains(key_);
}

void Client::delete_key(std::string_view key) {
dragon::SerializableString key_{std::string{key}};
ddict.erase(key_);
}

void Client::put_bytes(std::string_view key, const void *bytes,
detail::MetaInt length) {
// FIXME: Gross const cast needed -- check with Kent\!\!
Expand Down
4 changes: 4 additions & 0 deletions src/cpp/smartredis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ bool Client::contains(std::string_view key) {
return client.key_exists(std::string{key});
}

void Client::delete_key(std::string_view key) {
client.delete_bytes(std::string{key});
}

void Client::put_bytes(std::string_view key, const void *bytes,
detail::MetaInt length) {
client.put_bytes(std::string{key}, bytes, length);
Expand Down
2 changes: 2 additions & 0 deletions src/python/src/radex/clients/core.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ cdef extern from "radex/client.hpp" namespace "radex":
void put_bytes(string_view, const void*, size_t) except +raise_py_error
BytesBuffer get_bytes(string_view) except +raise_py_error
BytesBuffer wait_for_bytes(string_view, milliseconds) except +raise_py_error
void delete_key(string_view) except +
# <<< End Virtual Methods <<<

void put_scalar[T](const OutgoingHandle&, T) except +raise_py_error
Expand All @@ -35,3 +36,4 @@ cdef extern from "radex/client.hpp" namespace "radex":
unique_ptr[ItemInfo] get_item_info_ptr(const IncomingHandle&) except +raise_py_error
unique_ptr[ItemInfo] wait_for_item_info_ptr(
const IncomingHandle&, milliseconds) except +raise_py_error
void delete_item(const OutgoingHandle&) except +raise_py_error
4 changes: 4 additions & 0 deletions src/python/src/radex/clients/core.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ cdef class PyClient:
cdef np.number val = coerce_py_objects_to_np_numbers(value)
return self._put_scalar(handle, val)

def delete_item(self, OutgoingHandle handle):
"""Delete a typed value and its associated metadata."""
self._client.delete_item(handle.unwrap()[0])

def _put_scalar(self, OutgoingHandle handle, np.number value not None):
# FIXME: Get rid of this ugly swith statment. Ideally we could used the
# fused `SupportedType` type, but there seems to be a known
Expand Down
34 changes: 34 additions & 0 deletions tests/cpp/test_local_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ class UnorderedMapClient : public radex::IClient {
return true;
}

private:
void delete_key(std::string_view key) override {
_map.erase(std::string{key});
}

public:
void put_bytes(std::string_view key, const void *bytes,
radex::detail::MetaInt length) override {
auto ptr = static_cast<const std::uint8_t *>(bytes);
Expand Down Expand Up @@ -75,6 +81,34 @@ TEMPLATE_TEST_CASE("In memory client test cases", "[in-mem]", std::int32_t,
}
}

SECTION("Client can delete a scalar value and its metadata") {
const radex::data::OutgoingHandle outgoing{"my-scalar"};
const radex::data::OutgoingHandle deletion_handle{"my-scalar"};
client.put_scalar(outgoing, TestType{});
REQUIRE(client.contains(outgoing.key()));
REQUIRE(client.contains(outgoing.metadata_key()));

client.delete_item(deletion_handle);

REQUIRE_FALSE(client.contains(outgoing.key()));
REQUIRE_FALSE(client.contains(outgoing.metadata_key()));
}

SECTION("Client can delete a tensor value and its metadata") {
const radex::data::OutgoingHandle outgoing{"my-tensor-to-delete"};
const radex::data::OutgoingHandle deletion_handle{"my-tensor-to-delete"};
const std::vector<radex::detail::MetaInt> dims{2};
const std::vector<TestType> data{TestType{1}, TestType{2}};
client.put_tensor(outgoing, dims, data);
REQUIRE(client.contains(outgoing.key()));
REQUIRE(client.contains(outgoing.metadata_key()));

client.delete_item(deletion_handle);

REQUIRE_FALSE(client.contains(outgoing.key()));
REQUIRE_FALSE(client.contains(outgoing.metadata_key()));
}

SECTION("Client can put and get a 1D tensor value") {
const int size = 12;
std::vector<TestType> x_data(size);
Expand Down
24 changes: 24 additions & 0 deletions tests/python/dragon/test_delete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import pytest

from radex.handles.handles import IncomingHandle, OutgoingHandle


def test_delete_typed_item(client, random_np_value):
key = "some-value-to-delete"
client.put_scalar(OutgoingHandle(key), random_np_value)
assert client.contains(key)

client.delete_item(OutgoingHandle(key))

assert not client.contains(key)
assert not client.contains(f"meta::{key}")


def test_delete_raw_key(client, random_picklable):
key = "some-object-to-delete"
client.put_picklable(key, random_picklable)
assert client.contains(key)

client.delete_item(OutgoingHandle(key))

assert not client.contains(key)
Loading