void save_binary_chunk(void const* address, std::size_t count) // override { if (filter_ || chunks_ == 0 || count < HPX_ZERO_COPY_SERIALIZATION_THRESHOLD) { // fall back to serialization_chunk-less archive this->output_container::save_binary(address, count); } else { HPX_ASSERT(get_num_chunks() > current_chunk_); HPX_ASSERT( get_chunk_type(current_chunk_) == chunk_type_index || get_chunk_size(current_chunk_) != 0); // complement current serialization_chunk by setting its length if (get_chunk_type(current_chunk_) == chunk_type_index) { HPX_ASSERT(get_chunk_size(current_chunk_) == 0); set_chunk_size(current_chunk_, current_ - get_chunk_data(current_chunk_).index_); } // add a new serialization_chunk referring to the external buffer chunks_->push_back(create_pointer_chunk(address, count)); ++current_chunk_; } }
void load_binary_chunk(void* address, std::size_t count) // override { HPX_ASSERT((std::int64_t)count >= 0); if (chunks_ == nullptr || count < HPX_ZERO_COPY_SERIALIZATION_THRESHOLD || filter_) { // fall back to serialization_chunk-less archive this->input_container::load_binary(address, count); } else { HPX_ASSERT(current_chunk_ != std::size_t(-1)); HPX_ASSERT(get_chunk_type(current_chunk_) == chunk_type_pointer); if (get_chunk_size(current_chunk_) != count) { HPX_THROW_EXCEPTION(serialization_error , "input_container::load_binary_chunk" , "archive data bstream data chunk size mismatch"); return; } // unfortunately we can't implement a zero copy policy on // the receiving end // as the memory was already allocated by the serialization code std::memcpy(address, get_chunk_data(current_chunk_).pos_, count); ++current_chunk_; } }
void save_binary(void const* address, std::size_t count) // override { HPX_ASSERT(count != 0); { if (filter_) { filter_->save(address, count); } else { // make sure there is a current serialization_chunk descriptor // available if (chunks_) { HPX_ASSERT(get_num_chunks() > current_chunk_); if (get_chunk_type(current_chunk_) == chunk_type_pointer || get_chunk_size(current_chunk_) != 0) { // add a new serialization_chunk chunks_->push_back(create_index_chunk(current_, 0)); ++current_chunk_; } } if (cont_.size() < current_ + count) cont_.resize(cont_.size() + count); if (count == 1) cont_[current_] = *static_cast<unsigned char const*>(address); else std::memcpy(&cont_[current_], address, count); } current_ += count; } }
~output_container() { if (filter_) { std::size_t written = 0; if (cont_.size() < current_) cont_.resize(current_); current_ = start_compressing_at_; do { bool flushed = filter_->flush(&cont_[current_], cont_.size()-current_, written); current_ += written; if (flushed) break; // resize container cont_.resize(cont_.size()*2); } while (true); cont_.resize(current_); // truncate container } else if (chunks_) { HPX_ASSERT(get_num_chunks() > current_chunk_); HPX_ASSERT( get_chunk_type(current_chunk_) == chunk_type_index || get_chunk_size(current_chunk_) != 0); // complement current serialization_chunk by setting its length if (get_chunk_type(current_chunk_) == chunk_type_index) { HPX_ASSERT(get_chunk_size(current_chunk_) == 0); set_chunk_size(current_chunk_, current_ - get_chunk_data(current_chunk_).index_); } } }
void save_binary(void const* address, std::size_t count) // override { HPX_ASSERT(count != 0); { if (filter_) { filter_->save(address, count); } else { // make sure there is a current serialization_chunk descriptor // available if (chunks_) { HPX_ASSERT(get_num_chunks() > current_chunk_); if (get_chunk_type(current_chunk_) == chunk_type_pointer || get_chunk_size(current_chunk_) != 0) { // add a new serialization_chunk, reuse chunks, // if possible // the chunk size will be set at the end if (chunks_->size() <= current_chunk_ + 1) { chunks_->push_back( create_index_chunk(current_, 0)); ++current_chunk_; } else { (*chunks_)[++current_chunk_] = create_index_chunk(current_, 0); } } } if (cont_.size() < current_ + count) cont_.resize(cont_.size() + count); detail::access_data<Container>::write( cont_, count, current_, address); } current_ += count; } }