aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-06-24 22:54:04 +0200
committerSven Gothel <[email protected]>2020-06-24 22:54:04 +0200
commit3cf7e59c2dbd20e1e781d90d9308a56fd449e040 (patch)
treeec217f2571dbb2a4c71930089ac11b8cad0bb77c
parent766ef519b8ada7711f059ea28f3073f50934b3f0 (diff)
*Ringbuffer: Add 'drop(int count)' method, dropping max count oldest elements
-rw-r--r--api/direct_bt/LFRingbuffer.hpp23
-rw-r--r--api/direct_bt/Ringbuffer.hpp10
2 files changed, 33 insertions, 0 deletions
diff --git a/api/direct_bt/LFRingbuffer.hpp b/api/direct_bt/LFRingbuffer.hpp
index 14447664..ebaaa6a0 100644
--- a/api/direct_bt/LFRingbuffer.hpp
+++ b/api/direct_bt/LFRingbuffer.hpp
@@ -34,6 +34,7 @@
#include <mutex>
#include <condition_variable>
#include <chrono>
+#include <algorithm>
#include "BasicTypes.hpp"
@@ -188,6 +189,24 @@ template <typename T, std::nullptr_t nullelem> class LFRingbuffer : public Ringb
return r;
}
+ int dropImpl (const int count) {
+ // locks ringbuffer completely (read/write), hence no need for local copy nor wait/sync etc
+ std::unique_lock<std::mutex> lockMultiRead(syncMultiRead); // RAII-style acquire and relinquish via destructor
+ std::unique_lock<std::mutex> lockMultiWrite(syncMultiWrite); // ditto
+
+ const int dropCount = std::min(count, size.load());
+ if( 0 == dropCount ) {
+ return 0;
+ }
+ for(int i=0; i<dropCount; i++) {
+ readPos = (readPos + 1) % capacityPlusOne;
+ // T r = array[localReadPos];
+ array[readPos] = nullelem;
+ size--;
+ }
+ return dropCount;
+ }
+
bool putImpl(const T &e, const bool sameRef, const bool blocking, const int timeoutMS) /* throws InterruptedException */ {
std::unique_lock<std::mutex> lockMultiWrite(syncMultiWrite); // RAII-style acquire and relinquish via destructor
@@ -373,6 +392,10 @@ template <typename T, std::nullptr_t nullelem> class LFRingbuffer : public Ringb
return getImpl(true, true, timeoutMS);
}
+ int drop(const int count) override {
+ return dropImpl(count);
+ }
+
bool put(const T & e) override {
return putImpl(e, false, false, 0);
}
diff --git a/api/direct_bt/Ringbuffer.hpp b/api/direct_bt/Ringbuffer.hpp
index 692dbdf0..4a4c525c 100644
--- a/api/direct_bt/Ringbuffer.hpp
+++ b/api/direct_bt/Ringbuffer.hpp
@@ -137,6 +137,16 @@ template <class T> class Ringbuffer {
virtual T peekBlocking(const int timeoutMS=0) /* throws InterruptedException */ = 0;
/**
+ * Drops up to {@code count} oldest enqueued elements.
+ * <p>
+ * Method is non blocking and returns immediately;.
+ * </p>
+ * @param count maximum number of elements to drop from ringbuffer.
+ * @return actual number of dropped elements.
+ */
+ virtual int drop(const int count) = 0;
+
+ /**
* Enqueues the given element.
* <p>
* Returns true if successful, otherwise false in case buffer is full.