]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/util/aligned_buffer.h
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under the BSD-style license found in the
3 // LICENSE file in the root directory of this source tree. An additional grant
4 // of patent rights can be found in the PATENTS file in the same directory.
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
12 #include "port/port.h"
16 inline size_t TruncateToPageBoundary(size_t page_size
, size_t s
) {
17 s
-= (s
& (page_size
- 1));
18 assert((s
% page_size
) == 0);
22 inline size_t Roundup(size_t x
, size_t y
) {
23 return ((x
+ y
- 1) / y
) * y
;
26 // This class is to manage an aligned user
27 // allocated buffer for direct I/O purposes
28 // though can be used for any purpose.
31 std::unique_ptr
<char[]> buf_
;
44 AlignedBuffer(AlignedBuffer
&& o
) ROCKSDB_NOEXCEPT
{
48 AlignedBuffer
& operator=(AlignedBuffer
&& o
) ROCKSDB_NOEXCEPT
{
49 alignment_
= std::move(o
.alignment_
);
50 buf_
= std::move(o
.buf_
);
51 capacity_
= std::move(o
.capacity_
);
52 cursize_
= std::move(o
.cursize_
);
53 bufstart_
= std::move(o
.bufstart_
);
57 AlignedBuffer(const AlignedBuffer
&) = delete;
59 AlignedBuffer
& operator=(const AlignedBuffer
&) = delete;
61 static bool isAligned(const void* ptr
, size_t alignment
) {
62 return reinterpret_cast<uintptr_t>(ptr
) % alignment
== 0;
65 static bool isAligned(size_t n
, size_t alignment
) {
66 return n
% alignment
== 0;
69 size_t Alignment() const {
73 size_t Capacity() const {
77 size_t CurrentSize() const {
81 const char* BufferStart() const {
85 char* BufferStart() { return bufstart_
; }
91 void Alignment(size_t alignment
) {
92 assert(alignment
> 0);
93 assert((alignment
& (alignment
- 1)) == 0);
94 alignment_
= alignment
;
97 // Allocates a new buffer and sets bufstart_ to the aligned first byte
98 void AllocateNewBuffer(size_t requestedCapacity
) {
100 assert(alignment_
> 0);
101 assert((alignment_
& (alignment_
- 1)) == 0);
103 size_t size
= Roundup(requestedCapacity
, alignment_
);
104 buf_
.reset(new char[size
+ alignment_
]);
106 char* p
= buf_
.get();
107 bufstart_
= reinterpret_cast<char*>(
108 (reinterpret_cast<uintptr_t>(p
)+(alignment_
- 1)) &
109 ~static_cast<uintptr_t>(alignment_
- 1));
114 // Returns the number of bytes appended
115 size_t Append(const char* src
, size_t append_size
) {
116 size_t buffer_remaining
= capacity_
- cursize_
;
117 size_t to_copy
= std::min(append_size
, buffer_remaining
);
120 memcpy(bufstart_
+ cursize_
, src
, to_copy
);
126 size_t Read(char* dest
, size_t offset
, size_t read_size
) const {
127 assert(offset
< cursize_
);
128 size_t to_read
= std::min(cursize_
- offset
, read_size
);
130 memcpy(dest
, bufstart_
+ offset
, to_read
);
136 void PadToAlignmentWith(int padding
) {
137 size_t total_size
= Roundup(cursize_
, alignment_
);
138 size_t pad_size
= total_size
- cursize_
;
141 assert((pad_size
+ cursize_
) <= capacity_
);
142 memset(bufstart_
+ cursize_
, padding
, pad_size
);
143 cursize_
+= pad_size
;
147 // After a partial flush move the tail to the beginning of the buffer
148 void RefitTail(size_t tail_offset
, size_t tail_size
) {
150 memmove(bufstart_
, bufstart_
+ tail_offset
, tail_size
);
152 cursize_
= tail_size
;
155 // Returns place to start writing
156 char* Destination() {
157 return bufstart_
+ cursize_
;
160 void Size(size_t cursize
) {