CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ring_buffer.cc
Go to the documentation of this file.
1 
5 #include "ring_buffer.h"
6 
7 #include <algorithm>
8 #include <cassert>
9 #include <cstdlib>
10 #include <cstring>
11 
12 #include "util/smalloc.h"
13 
15 
16 
17 RingBuffer::RingBuffer(size_t total_size)
18  : total_size_(total_size)
19  , free_space_(total_size)
20  , front_(0)
21  , back_(0)
22  , buffer_(reinterpret_cast<unsigned char *>(sxmmap(total_size_))) {
23  assert(total_size_ >= sizeof(size_t));
24 }
25 
26 
28 
29 
30 void RingBuffer::Put(const void *data, size_t size) {
31  const size_t size_head = std::min(size, total_size_ - front_);
32  if (size_head > 0)
33  memcpy(buffer_ + front_, data, size_head);
34 
35  if (size_head < size) {
36  const size_t size_tail = size - size_head;
37  memcpy(buffer_, reinterpret_cast<const unsigned char *>(data) + size_head,
38  size_tail);
39  }
40 
41  front_ = (front_ + size) % total_size_;
42  free_space_ -= size;
43 }
44 
45 
46 void RingBuffer::Get(size_t from, size_t size, void *to) const {
47  const size_t size_head = std::min(size, total_size_ - from);
48  if (size_head > 0)
49  memcpy(to, buffer_ + from, size_head);
50 
51  if (size_head < size) {
52  const size_t size_tail = size - size_head;
53  memcpy(reinterpret_cast<unsigned char *>(to) + size_head, buffer_,
54  size_tail);
55  }
56 }
57 
58 
59 void RingBuffer::Shrink(size_t by) {
60  back_ = (back_ + by) % total_size_;
61  free_space_ += by;
62 }
63 
64 
66  size_t size_tag;
67  Get(handle, sizeof(size_tag), &size_tag);
68  assert(size_tag <= total_size_);
69  return size_tag;
70 }
71 
72 
74  size_t size_tag = size;
75  size += sizeof(size_tag);
76  if (size > free_space_) {
77  return kInvalidObjectHandle;
78  }
79 
80  ObjectHandle_t result = front_;
81 
82  Put(&size_tag, sizeof(size_tag));
83  Put(obj, size_tag);
84 
85  return result;
86 }
87 
88 
90  ObjectHandle_t result = back_;
91 
92  size_t size_tag = GetObjectSize(result);
93  Shrink(sizeof(size_tag));
94  Shrink(size_tag);
95 
96  return result;
97 }
98 
99 
100 void RingBuffer::CopyObject(ObjectHandle_t handle, void *to) const {
101  size_t size_tag = GetObjectSize(handle);
102  ObjectHandle_t object = (handle + sizeof(size_tag)) % total_size_;
103  Get(object, size_tag, to);
104 }
105 
106 
107 void RingBuffer::CopySlice(ObjectHandle_t handle, size_t size, size_t offset,
108  void *to) const {
109  ObjectHandle_t begin = (handle + sizeof(size_t) + offset) % total_size_;
110  Get(begin, size, to);
111 }
ObjectHandle_t PushFront(const void *obj, size_t size)
Definition: ring_buffer.cc:73
size_t GetObjectSize(ObjectHandle_t handle) const
Definition: ring_buffer.cc:65
size_t front_
Definition: ring_buffer.h:93
void Put(const void *data, size_t size)
Definition: ring_buffer.cc:30
ObjectHandle_t RemoveBack()
Definition: ring_buffer.cc:89
RingBuffer(size_t total_size)
Definition: ring_buffer.cc:17
size_t free_space_
Definition: ring_buffer.h:89
assert((mem||(size==0))&&"Out Of Memory")
const size_t total_size_
Definition: ring_buffer.h:85
void CopySlice(ObjectHandle_t handle, size_t size, size_t offset, void *to) const
Definition: ring_buffer.cc:107
void Get(size_t from, size_t size, void *to) const
Definition: ring_buffer.cc:46
unsigned char * buffer_
Definition: ring_buffer.h:101
size_t ObjectHandle_t
Definition: ring_buffer.h:22
static const ObjectHandle_t kInvalidObjectHandle
Definition: ring_buffer.h:23
void Shrink(size_t by)
Definition: ring_buffer.cc:59
size_t back_
Definition: ring_buffer.h:97
void CopyObject(ObjectHandle_t handle, void *to) const
Definition: ring_buffer.cc:100
static void size_t size
Definition: smalloc.h:54