CernVM-FS  2.12.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 {
24  assert(total_size_ >= sizeof(size_t));
25 }
26 
27 
29  sxunmap(buffer_, total_size_);
30 }
31 
32 
33 void RingBuffer::Put(const void *data, size_t size) {
34  const size_t size_head = std::min(size, total_size_ - front_);
35  if (size_head > 0)
36  memcpy(buffer_ + front_, data, size_head);
37 
38  if (size_head < size) {
39  const size_t size_tail = size - size_head;
40  memcpy(buffer_, reinterpret_cast<const unsigned char *>(data) + size_head,
41  size_tail);
42  }
43 
44  front_ = (front_ + size) % total_size_;
45  free_space_ -= size;
46 }
47 
48 
49 void RingBuffer::Get(size_t from, size_t size, void *to) const {
50  const size_t size_head = std::min(size, total_size_ - from);
51  if (size_head > 0)
52  memcpy(to, buffer_ + from, size_head);
53 
54  if (size_head < size) {
55  const size_t size_tail = size - size_head;
56  memcpy(reinterpret_cast<unsigned char *>(to) + size_head, buffer_,
57  size_tail);
58  }
59 }
60 
61 
62 void RingBuffer::Shrink(size_t by) {
63  back_ = (back_ + by) % total_size_;
64  free_space_ += by;
65 }
66 
67 
69  size_t size_tag;
70  Get(handle, sizeof(size_tag), &size_tag);
71  assert(size_tag <= total_size_);
72  return size_tag;
73 }
74 
75 
77  size_t size_tag = size;
78  size += sizeof(size_tag);
79  if (size > free_space_) {
80  return kInvalidObjectHandle;
81  }
82 
83  ObjectHandle_t result = front_;
84 
85  Put(&size_tag, sizeof(size_tag));
86  Put(obj, size_tag);
87 
88  return result;
89 }
90 
91 
93  ObjectHandle_t result = back_;
94 
95  size_t size_tag = GetObjectSize(result);
96  Shrink(sizeof(size_tag));
97  Shrink(size_tag);
98 
99  return result;
100 }
101 
102 
103 void RingBuffer::CopyObject(ObjectHandle_t handle, void *to) const
104 {
105  size_t size_tag = GetObjectSize(handle);
106  ObjectHandle_t object = (handle + sizeof(size_tag)) % total_size_;
107  Get(object, size_tag, to);
108 }
109 
110 
111 void RingBuffer::CopySlice(ObjectHandle_t handle, size_t size, size_t offset,
112  void *to) const
113 {
114  ObjectHandle_t begin = (handle + sizeof(size_t) + offset) % total_size_;
115  Get(begin, size, to);
116 }
ObjectHandle_t PushFront(const void *obj, size_t size)
Definition: ring_buffer.cc:76
size_t GetObjectSize(ObjectHandle_t handle) const
Definition: ring_buffer.cc:68
size_t front_
Definition: ring_buffer.h:93
void Put(const void *data, size_t size)
Definition: ring_buffer.cc:33
ObjectHandle_t RemoveBack()
Definition: ring_buffer.cc:92
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:111
void Get(size_t from, size_t size, void *to) const
Definition: ring_buffer.cc:49
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:62
size_t back_
Definition: ring_buffer.h:97
void CopyObject(ObjectHandle_t handle, void *to) const
Definition: ring_buffer.cc:103
static void size_t size
Definition: smalloc.h:54