From 1524ac986ff38ec691062b82e821f09aa6011524 Mon Sep 17 00:00:00 2001 From: Harihara Kadayam Date: Thu, 12 Jan 2023 17:18:05 -0800 Subject: [PATCH] Expand buffer functionality (#389) --- include/libnuraft/buffer.hxx | 14 ++++++++++++++ src/buffer.cxx | 20 +++++++++++++++++++- tests/unit/buffer_test.cxx | 14 ++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/include/libnuraft/buffer.hxx b/include/libnuraft/buffer.hxx index f4885fb6..bda6f483 100644 --- a/include/libnuraft/buffer.hxx +++ b/include/libnuraft/buffer.hxx @@ -64,6 +64,20 @@ public: */ static ptr clone(const buffer& buf); + /** + * Expand the current buffer to new size (which is expected to + * bigger than current size) and return a new buffer. It will copy + * the existing buffer. + * + * WARNING: It will still retain the current position of the passed + * buffer and the new ptr buffer (i.e. ret_buf->pos() == buf->pos()) + * + * @param buf Pointer to buffer which will be realloced + * @param new_size New size of the buffer + * @return Expanded buffer instance + */ + static ptr expand(const buffer& buf, uint32_t new_size); + /** * Get total size of entire buffer container, including meta section. * diff --git a/src/buffer.cxx b/src/buffer.cxx index 4d1ff965..f901e5ed 100644 --- a/src/buffer.cxx +++ b/src/buffer.cxx @@ -97,7 +97,7 @@ ptr buffer::alloc(const size_t size) { if (size >= 0x80000000) { throw std::out_of_range( "size exceed the max size that " - "cornrestone::buffer could support" ); + "nuraft::buffer could support" ); } num_allocs++; num_active++; @@ -144,6 +144,24 @@ ptr buffer::clone(const buffer& buf) { return other; } +ptr buffer::expand(const buffer& buf, uint32_t new_size) { + if (new_size >= 0x80000000) { + throw std::out_of_range( "size exceed the max size that " + "nuraft::buffer could support" ); + } + + if (new_size < buf.size()) { + throw std::out_of_range( "realloc() new_size is less than " + "old size" ); + } + ptr other = alloc(new_size); + byte* dst = other->data_begin(); + byte* src = buf.data_begin(); + ::memcpy(dst, src, buf.size()); + other->pos(buf.pos()); + return other; +} + size_t buffer::container_size() const { return (size_t)( __size_of_block(this) + ( ( __is_big_block(this) ) diff --git a/tests/unit/buffer_test.cxx b/tests/unit/buffer_test.cxx index d7b83aac..0b51b52f 100644 --- a/tests/unit/buffer_test.cxx +++ b/tests/unit/buffer_test.cxx @@ -117,6 +117,20 @@ int buffer_basic_test(size_t buf_size) { ulong long_val_copy = lbuf1->get_ulong(); CHK_EQ( long_val, long_val_copy ); + ptr buf4(buffer::alloc(sz_int * 100)); + buf4->pos(0); + for (int i = 0; i < 100; ++i) { + buf4->put(i); + } + buf4 = buffer::expand(*buf4, sz_int * 200); + for (int i = 0; i < 100; ++i) { + buf4->put(i + 100); + } + buf4->pos(0); + for (int i = 0; i < 200; ++i) { + int32 val = buf4->get_int(); + CHK_EQ( i, val ); + } return 0; }