summaryrefslogtreecommitdiffstats
path: root/storage/tokudb/tokudb_buffer.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:07:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:07:14 +0000
commita175314c3e5827eb193872241446f2f8f5c9d33c (patch)
treecd3d60ca99ae00829c52a6ca79150a5b6e62528b /storage/tokudb/tokudb_buffer.h
parentInitial commit. (diff)
downloadmariadb-10.5-upstream.tar.xz
mariadb-10.5-upstream.zip
Adding upstream version 1:10.5.12.upstream/1%10.5.12upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'storage/tokudb/tokudb_buffer.h')
-rw-r--r--storage/tokudb/tokudb_buffer.h187
1 files changed, 187 insertions, 0 deletions
diff --git a/storage/tokudb/tokudb_buffer.h b/storage/tokudb/tokudb_buffer.h
new file mode 100644
index 00000000..1605543c
--- /dev/null
+++ b/storage/tokudb/tokudb_buffer.h
@@ -0,0 +1,187 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+#ident "$Id$"
+/*======
+This file is part of TokuDB
+
+
+Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
+
+ TokuDBis is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2,
+ as published by the Free Software Foundation.
+
+ TokuDB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with TokuDB. If not, see <http://www.gnu.org/licenses/>.
+
+======= */
+
+#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
+
+#ifndef _TOKUDB_BUFFER_H
+#define _TOKUDB_BUFFER_H
+
+#include "hatoku_defines.h"
+#include "tokudb_debug.h"
+#include "tokudb_thread.h"
+#include "tokudb_vlq.h"
+
+namespace tokudb {
+
+// A Buffer manages a contiguous chunk of memory and supports appending new
+// data to the end of the buffer, and consuming chunks from the beginning of
+// the buffer. The buffer will reallocate memory when appending new data to
+// a full buffer.
+
+class buffer {
+public:
+ inline buffer(
+ void* the_data,
+ size_t s,
+ size_t l) :
+ m_data(the_data),
+ m_size(s),
+ m_limit(l),
+ m_is_static(true) {
+ }
+ inline buffer() :
+ m_data(NULL),
+ m_size(0),
+ m_limit(0),
+ m_is_static(false) {
+ }
+ virtual ~buffer() {
+ if (!m_is_static)
+ free(m_data);
+ }
+
+ // Return a pointer to the end of the buffer suitable for appending a
+ // fixed number of bytes.
+ void* append_ptr(size_t s) {
+ maybe_realloc(s);
+ void* p = (char*)m_data + m_size;
+ m_size += s;
+ return p;
+ }
+
+ // Append bytes to the buffer
+ void append(void* p, size_t s) {
+ memcpy(append_ptr(s), p, s);
+ }
+
+ // Append an unsigned int to the buffer.
+ // Returns the number of bytes used to encode the number.
+ // Returns 0 if the number could not be encoded.
+ template<class T> size_t append_ui(T n) {
+ maybe_realloc(10); // 10 bytes is big enough for up to 64 bit number
+ size_t s = tokudb::vlq_encode_ui<T>(n, (char *) m_data + m_size, 10);
+ m_size += s;
+ return s;
+ }
+
+ // Return a pointer to the next location in the buffer where bytes are
+ // consumed from.
+ void* consume_ptr(size_t s) {
+ if (m_size + s > m_limit)
+ return NULL;
+ void* p = (char*)m_data + m_size;
+ m_size += s;
+ return p;
+ }
+
+ // Consume bytes from the buffer.
+ void consume(void* p, size_t s) {
+ memcpy(p, consume_ptr(s), s);
+ }
+
+ // Consume an unsigned int from the buffer.
+ // Returns 0 if the unsigned int could not be decoded, probably because
+ // the buffer is too short.
+ // Otherwise return the number of bytes consumed, and stuffs the decoded
+ // number in *p.
+ template<class T> size_t consume_ui(T* p) {
+ size_t s = tokudb::vlq_decode_ui<T>(
+ p,
+ (char*)m_data + m_size,
+ m_limit - m_size);
+ m_size += s;
+ return s;
+ }
+
+ // Write p_length bytes at an offset in the buffer
+ void write(void* p, size_t p_length, size_t offset) {
+ assert_always(offset + p_length <= m_size);
+ memcpy((char*)m_data + offset, p, p_length);
+ }
+
+ // Read p_length bytes at an offset in the buffer
+ void read(void* p, size_t p_length, size_t offset) {
+ assert_always(offset + p_length <= m_size);
+ memcpy(p, (char*)m_data + offset, p_length);
+ }
+
+ // Replace a field in the buffer with new data. If the new data size is
+ // different, then readjust the size of the buffer and move things around.
+ void replace(size_t offset, size_t old_s, void* new_p, size_t new_s) {
+ assert_always(offset + old_s <= m_size);
+ if (new_s > old_s)
+ maybe_realloc(new_s - old_s);
+ char* data_offset = (char*)m_data + offset;
+ if (new_s != old_s) {
+ size_t n = m_size - (offset + old_s);
+ assert_always(offset + new_s + n <= m_limit);
+ assert_always(offset + old_s + n <= m_limit);
+ memmove(data_offset + new_s, data_offset + old_s, n);
+ if (new_s > old_s)
+ m_size += new_s - old_s;
+ else
+ m_size -= old_s - new_s;
+ assert_always(m_size <= m_limit);
+ }
+ memcpy(data_offset, new_p, new_s);
+ }
+
+ // Return a pointer to the data in the buffer
+ void* data() const {
+ return m_data;
+ }
+
+ // Return the size of the data in the buffer
+ size_t size() const {
+ return m_size;
+ }
+
+ // Return the size of the underlying memory in the buffer
+ size_t limit() const {
+ return m_limit;
+ }
+
+private:
+ // Maybe reallocate the buffer when it becomes full by doubling its size.
+ void maybe_realloc(size_t s) {
+ if (m_size + s > m_limit) {
+ size_t new_limit = m_limit * 2;
+ if (new_limit < m_size + s)
+ new_limit = m_size + s;
+ assert_always(!m_is_static);
+ void *new_data = realloc(m_data, new_limit);
+ assert_always(new_data != NULL);
+ m_data = new_data;
+ m_limit = new_limit;
+ }
+ }
+private:
+ void* m_data;
+ size_t m_size;
+ size_t m_limit;
+ bool m_is_static;
+};
+
+};
+
+#endif