24 #ifndef GRAPHLAB_RPC_CIRCULAR_IOVEC_BUFFER_HPP
25 #define GRAPHLAB_RPC_CIRCULAR_IOVEC_BUFFER_HPP
27 #include <sys/socket.h>
40 struct circular_iovec_buffer {
41 inline circular_iovec_buffer(
size_t len = 4096) {
43 parallel_v.resize(4096);
49 inline bool empty()
const {
58 void reserve(
size_t _n) {
59 if (_n <= v.size())
return;
60 size_t originalsize = v.size();
63 while (n <= _n) n *= 2;
67 if (head >= tail && numel > 0) {
70 size_t newtail = originalsize;
71 for (
size_t i = 0;i < tail; ++i) {
73 parallel_v[newtail] = parallel_v[i];
80 inline void write(
const std::vector<iovec>& other,
size_t nwrite) {
81 reserve(numel + nwrite);
82 for (
size_t i = 0;i < nwrite; ++i) {
84 parallel_v[tail] = other[i];
85 tail = (tail + 1) & (v.size() - 1);
95 inline void write(
const iovec &entry) {
96 if (numel == v.size()) {
101 parallel_v[tail] = entry;
102 tail = (tail + 1) & (v.size() - 1); ++numel;
113 inline void write(
const iovec &entry,
const iovec& actual_ptr_entry) {
114 if (numel == v.size()) {
118 v[tail] = actual_ptr_entry;
119 parallel_v[tail] = entry;
120 tail = (tail + 1) & (v.size() - 1); ++numel;
127 inline void erase_from_head_and_free() {
128 free(v[head].iov_base);
129 head = (head + 1) & (v.size() - 1);
136 void fill_msghdr(
struct msghdr& data) {
137 data.msg_iov = &(parallel_v[head]);
139 data.msg_iovlen = tail - head;
142 data.msg_iovlen = v.size() - head;
144 data.msg_iovlen = std::min<size_t>(IOV_MAX, data.msg_iovlen);
150 void sent(
size_t len) {
152 size_t curv_sent_len = std::min(len, parallel_v[head].iov_len);
153 parallel_v[head].iov_len -= curv_sent_len;
154 parallel_v[head].iov_base = (
char*)(parallel_v[head].iov_base) + curv_sent_len;
155 len -= curv_sent_len;
156 if (parallel_v[head].iov_len == 0) {
157 erase_from_head_and_free();
162 std::vector<struct iovec> v;
163 std::vector<struct iovec> parallel_v;