diff --git a/tddb/td/db/TQueue.cpp b/tddb/td/db/TQueue.cpp index 899998b47..1f7c65c2f 100644 --- a/tddb/td/db/TQueue.cpp +++ b/tddb/td/db/TQueue.cpp @@ -215,6 +215,18 @@ class TQueueImpl final : public TQueue { pop(q, queue_id, it, q.tail_id); } + void clear(QueueId queue_id, size_t keep_count) final { + auto size = get_size(queue_id); + if (size <= keep_count) { + return; + } + + MutableSpan span; + auto r_size = get(queue_id, get_tail(queue_id).advance(0 - keep_count).move_as_ok(), true, 0, span); + CHECK(r_size.is_ok()); + CHECK(r_size.ok() == keep_count); + } + Result get(QueueId queue_id, EventId from_id, bool forget_previous, int32 unix_time_now, MutableSpan &result_events) final { auto it = queues_.find(queue_id); diff --git a/tddb/td/db/TQueue.h b/tddb/td/db/TQueue.h index df8dbc5d1..117726851 100644 --- a/tddb/td/db/TQueue.h +++ b/tddb/td/db/TQueue.h @@ -104,6 +104,8 @@ class TQueue { virtual void forget(QueueId queue_id, EventId event_id) = 0; + virtual void clear(QueueId queue_id, size_t keep_count) = 0; + virtual EventId get_head(QueueId queue_id) const = 0; virtual EventId get_tail(QueueId queue_id) const = 0; diff --git a/test/tqueue.cpp b/test/tqueue.cpp index fe80a5491..3c4659f09 100644 --- a/test/tqueue.cpp +++ b/test/tqueue.cpp @@ -18,6 +18,7 @@ #include "td/utils/SliceBuilder.h" #include "td/utils/Span.h" #include "td/utils/tests.h" +#include "td/utils/Time.h" #include #include @@ -225,3 +226,25 @@ TEST(TQueue, memory_leak) { } } } + +TEST(TQueue, clear) { + auto tqueue = td::TQueue::create(); + + auto start_time = td::Time::now(); + td::int32 now = 0; + td::vector ids; + td::Random::Xorshift128plus rnd(123); + for (size_t i = 0; i < 1000000; i++) { + auto id = tqueue->push(1, td::string(td::Random::fast(100, 500), 'a'), now + 600000, 0, {}).move_as_ok(); + } + auto tail_id = tqueue->get_tail(1); + auto clear_start_time = td::Time::now(); + size_t keep_count = td::Random::fast(0, 2); + tqueue->clear(1, keep_count); + auto finish_time = td::Time::now(); + LOG(INFO) << "Added TQueue events in " << clear_start_time - start_time << " seconds and cleared them in " + << finish_time - clear_start_time << " seconds"; + CHECK(tqueue->get_size(1) == keep_count); + CHECK(tqueue->get_head(1).advance(keep_count).ok() == tail_id); + CHECK(tqueue->get_tail(1) == tail_id); +}