]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/rocksdb/util/aligned_buffer.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / rocksdb / util / aligned_buffer.h
index 2201b487770166494eaf415ca386525dc9cba1ab..c7b0728c9fe463181494e30fd7f16aefd655b771 100644 (file)
 #include <algorithm>
 #include "port/port.h"
 
-namespace rocksdb {
+namespace ROCKSDB_NAMESPACE {
 
+// This file contains utilities to handle the alignment of pages and buffers.
+
+// Truncate to a multiple of page_size, which is also a page boundary. This
+// helps to figuring out the right alignment.
+// Example:
+//   TruncateToPageBoundary(5000, 4096)  => 4096
+//   TruncateToPageBoundary(10000, 4096) => 8192
 inline size_t TruncateToPageBoundary(size_t page_size, size_t s) {
   s -= (s & (page_size - 1));
   assert((s % page_size) == 0);
   return s;
 }
 
+// Round up x to a multiple of y.
+// Example:
+//   Roundup(13, 5)   => 15
+//   Roundup(201, 16) => 208
 inline size_t Roundup(size_t x, size_t y) {
   return ((x + y - 1) / y) * y;
 }
 
+// Round down x to a multiple of y.
+// Example:
+//   Rounddown(13, 5)   => 10
+//   Rounddown(201, 16) => 192
 inline size_t Rounddown(size_t x, size_t y) { return (x / y) * y; }
 
-// This class is to manage an aligned user
-// allocated buffer for direct I/O purposes
-// though can be used for any purpose.
+// AlignedBuffer manages a buffer by taking alignment into consideration, and
+// aligns the buffer start and end positions. It is mainly used for direct I/O,
+// though it can be used other purposes as well.
+// It also supports expanding the managed buffer, and copying whole or part of
+// the data from old buffer into the new expanded buffer. Such a copy especially
+// helps in cases avoiding an IO to re-fetch the data from disk.
+//
+// Example:
+//   AlignedBuffer buf;
+//   buf.Alignment(alignment);
+//   buf.AllocateNewBuffer(user_requested_buf_size);
+//   ...
+//   buf.AllocateNewBuffer(2*user_requested_buf_size, /*copy_data*/ true,
+//                         copy_offset, copy_len);
 class AlignedBuffer {
   size_t alignment_;
   std::unique_ptr<char[]> buf_;
@@ -96,12 +122,21 @@ public:
     alignment_ = alignment;
   }
 
-  // Allocates a new buffer and sets bufstart_ to the aligned first byte.
+  // Allocates a new buffer and sets the start position to the first aligned
+  // byte.
+  //
   // requested_capacity: requested new buffer capacity. This capacity will be
   //     rounded up based on alignment.
-  // copy_data: Copy data from old buffer to new buffer.
+  // copy_data: Copy data from old buffer to new buffer. If copy_offset and
+  //     copy_len are not passed in and the new requested capacity is bigger
+  //     than the existing buffer's capacity, the data in the exising buffer is
+  //     fully copied over to the new buffer.
   // copy_offset: Copy data from this offset in old buffer.
   // copy_len: Number of bytes to copy.
+  //
+  // The function does nothing if the new requested_capacity is smaller than
+  // the current buffer capacity and copy_data is true i.e. the old buffer is
+  // retained as is.
   void AllocateNewBuffer(size_t requested_capacity, bool copy_data = false,
                          uint64_t copy_offset = 0, size_t copy_len = 0) {
     assert(alignment_ > 0);
@@ -110,7 +145,7 @@ public:
     copy_len = copy_len > 0 ? copy_len : cursize_;
     if (copy_data && requested_capacity < copy_len) {
       // If we are downsizing to a capacity that is smaller than the current
-      // data in the buffer. Ignore the request.
+      // data in the buffer -- Ignore the request.
       return;
     }
 
@@ -132,8 +167,15 @@ public:
     capacity_ = new_capacity;
     buf_.reset(new_buf);
   }
-  // Used for write
-  // Returns the number of bytes appended
+
+  // Append to the buffer.
+  //
+  // src         : source to copy the data from.
+  // append_size : number of bytes to copy from src.
+  // Returns the number of bytes appended.
+  //
+  // If append_size is more than the remaining buffer size only the
+  // remaining-size worth of bytes are copied.
   size_t Append(const char* src, size_t append_size) {
     size_t buffer_remaining = capacity_ - cursize_;
     size_t to_copy = std::min(append_size, buffer_remaining);
@@ -145,6 +187,12 @@ public:
     return to_copy;
   }
 
+  // Read from the buffer.
+  //
+  // dest      : destination buffer to copy the data to.
+  // offset    : the buffer offset to start reading from.
+  // read_size : the number of bytes to copy from the buffer to dest.
+  // Returns the number of bytes read/copied to dest.
   size_t Read(char* dest, size_t offset, size_t read_size) const {
     assert(offset < cursize_);
 
@@ -158,7 +206,7 @@ public:
     return to_read;
   }
 
-  /// Pad to alignment
+  // Pad to the end of alignment with "padding"
   void PadToAlignmentWith(int padding) {
     size_t total_size = Roundup(cursize_, alignment_);
     size_t pad_size = total_size - cursize_;
@@ -176,7 +224,7 @@ public:
     cursize_ += pad_size;
   }
 
-  // After a partial flush move the tail to the beginning of the buffer
+  // After a partial flush move the tail to the beginning of the buffer.
   void RefitTail(size_t tail_offset, size_t tail_size) {
     if (tail_size > 0) {
       memmove(bufstart_, bufstart_ + tail_offset, tail_size);
@@ -184,7 +232,11 @@ public:
     cursize_ = tail_size;
   }
 
-  // Returns place to start writing
+  // Returns a place to start appending.
+  // WARNING: Note that it is possible to write past the end of the buffer if
+  // the buffer is modified without using the write APIs or encapsulation
+  // offered by AlignedBuffer. It is up to the user to guard against such
+  // errors.
   char* Destination() {
     return bufstart_ + cursize_;
   }
@@ -193,4 +245,4 @@ public:
     cursize_ = cursize;
   }
 };
-}
+}  // namespace ROCKSDB_NAMESPACE