mpacklog — Log dictionaries to file using MessagePack  v2.1.0
CircularBuffer.h
Go to the documentation of this file.
1 /*
2  * Copyright 2022 Stéphane Caron
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * This file incorporates work covered by the following copyright and
17  * permission notice:
18  *
19  * CircularBuffer class of mc_rtc
20  * Copyright 2012-2019 CNRS-UM LIRMM, CNRS-AIST JRL
21  * License: BSD-2-Clause (see licenses/LICENSE-mc_rtc)
22  */
23 
24 #pragma once
25 
26 #include <spdlog/spdlog.h>
27 
28 #include <atomic>
29 
30 namespace mpacklog {
31 
37 template <typename T, size_t Size>
39  public:
40  enum { Capacity = Size + 1 };
41 
43  CircularBuffer() : head_(0), tail_(0) {
44  if (!tail_.is_lock_free()) {
45  spdlog::warn(
46  "Your platform does not support std::atomic_size_t as lock-free "
47  "operations");
48  }
49  }
50 
57  bool push(const T& item) {
58  size_t tail = tail_;
59  auto next_tail = increment(tail);
60  if (next_tail != head_) {
61  data_[tail] = item;
62  tail_ = next_tail;
63  return true;
64  }
65  return false;
66  }
67 
74  bool pop(T& item) {
75  const size_t head = head_;
76  if (head == tail_) {
77  return false;
78  }
79  item = data_[head];
80  head_ = increment(head);
81  return true;
82  }
83 
85  bool empty() { return head_ == tail_; }
86 
88  size_t size() { return (tail_ + Capacity - head_) % Capacity; }
89 
90  private:
97  size_t increment(size_t idx) const { return (idx + 1) % Capacity; }
98 
100  T data_[Capacity];
101 
103  std::atomic_size_t head_;
104 
106  std::atomic_size_t tail_;
107 };
108 
109 } // namespace mpacklog
mpacklog::CircularBuffer::push
bool push(const T &item)
Push data to the buffer.
Definition: CircularBuffer.h:57
mpacklog::CircularBuffer::empty
bool empty()
Check whether the buffer is empty.
Definition: CircularBuffer.h:85
mpacklog::CircularBuffer
Definition: CircularBuffer.h:38
mpacklog
Log action and observation dictionaries to MessagePack binary files.
Definition: CircularBuffer.h:30
mpacklog::CircularBuffer::pop
bool pop(T &item)
Pop next item from the buffer.
Definition: CircularBuffer.h:74
mpacklog::CircularBuffer::CircularBuffer
CircularBuffer()
Initialize buffer.
Definition: CircularBuffer.h:43
mpacklog::CircularBuffer::size
size_t size()
Number of items in the buffer.
Definition: CircularBuffer.h:88
mpacklog::CircularBuffer::Capacity
@ Capacity
Definition: CircularBuffer.h:40