unsigned write(const void* buf, unsigned len) { auto allowed = std::min(len, write_available()); memcpy(write_begin(), buf, allowed); mNumWritten += allowed; return allowed; }
ConstIterator push(ConstIterator begin, ConstIterator end, T * internal_buffer, size_t max_size) { // FIXME: avoid std::distance const size_t write_index = write_index_.load(memory_order_relaxed); // only written from push thread const size_t read_index = read_index_.load(memory_order_acquire); const size_t avail = write_available(write_index, read_index, max_size); if (avail == 0) return begin; size_t input_count = std::distance(begin, end); input_count = (std::min)(input_count, avail); size_t new_write_index = write_index + input_count; const ConstIterator last = boost::next(begin, input_count); if (write_index + input_count > max_size) { /* copy data in two sections */ const size_t count0 = max_size - write_index; const ConstIterator midpoint = boost::next(begin, count0); std::uninitialized_copy(begin, midpoint, internal_buffer + write_index); std::uninitialized_copy(midpoint, last, internal_buffer); new_write_index -= max_size; } else { std::uninitialized_copy(begin, last, internal_buffer + write_index); if (new_write_index == max_size) new_write_index = 0; } write_index_.store(new_write_index, memory_order_release); return last; }
size_t write_available(size_t max_size) const { size_t write_index = write_index_.load(memory_order_relaxed); const size_t read_index = read_index_.load(memory_order_acquire); return write_available(write_index, read_index, max_size); }