Skip to content
Snippets Groups Projects
Commit 2026f85c authored by Nikolay Shirokovskiy's avatar Nikolay Shirokovskiy Committed by Vladimir Davydov
Browse files

prbuf: add prbuf_max_record_size

This is the maximum record size we can store in the buffer.

Needed for:
  https://github.com/tarantool/tarantool-ee/issues/358

NO_DOC=internal
NO_CHANGELOG=internal

(cherry picked from commit 2c7490e7)
parent 53e2c35d
No related branches found
No related tags found
No related merge requests found
......@@ -73,7 +73,7 @@ static const size_t record_size_overhead = sizeof(struct prbuf_record);
static uint32_t
prbuf_record_alloc_size(size_t size)
{
return size + offsetof(struct prbuf_record, data);
return size + record_size_overhead;
}
/** Returns pointer to the next byte after end of given buffer. */
......@@ -138,10 +138,16 @@ prbuf_size(struct prbuf *buf)
return buf->header->size - sizeof(struct prbuf_header);
}
size_t
prbuf_max_record_size(struct prbuf *buf)
{
return prbuf_size(buf) - record_size_overhead;
}
void
prbuf_create(struct prbuf *buf, void *mem, size_t size)
{
assert(size > sizeof(struct prbuf_header));
assert(size > (sizeof(struct prbuf_header) + record_size_overhead));
#ifndef NDEBUG
memset(mem, '#', size);
#endif
......
......@@ -4,7 +4,6 @@
*
* Copyright 2010-2022, Tarantool AUTHORS, please see AUTHORS file.
*/
#include <stdbool.h>
#include <stddef.h>
/** Data entry of prbuf. Public analogue of struct prbuf_record. */
......@@ -59,6 +58,12 @@ prbuf_create(struct prbuf *buf, void *mem, size_t size);
int
prbuf_open(struct prbuf *buf, void *mem);
/**
* Maximum record size we can store in the buffer.
*/
size_t
prbuf_max_record_size(struct prbuf *buf);
/**
* Returns pointer to memory chunk sizeof @a size.
* Note that without further prbuf_commit() call this function may return
......
......@@ -328,6 +328,59 @@ test_buffer_prepared_large(void)
footer();
}
/**
* Check:
* - we can alloc record of prbuf_max_record_size
* - we can't alloc larger buffer
* - record of max size is actually usable
*/
static void
test_max_record_size(void)
{
header();
struct prbuf buf;
char mem[73];
char payload[73];
prbuf_create(&buf, mem, sizeof(mem));
int max_size = prbuf_max_record_size(&buf);
int i;
for (i = 0; i < max_size; i++)
payload[i] = (char)i;
char *p = prbuf_prepare(&buf, max_size);
ok(p != NULL, "not NULL is expected");
memcpy(p, payload, max_size);
prbuf_commit(&buf);
struct prbuf rbuf;
struct prbuf_iterator iter;
struct prbuf_entry entry;
if (prbuf_open(&rbuf, mem) != 0)
fail("prbuf_open", "not 0");
prbuf_iterator_create(&rbuf, &iter);
int rc = prbuf_iterator_next(&iter, &entry);
ok(rc == 0, "rc is %d", rc);
ok(entry.size == (size_t)max_size,
"expected %d got %zd", max_size, entry.size);
if (entry.size != (size_t)max_size)
fail("entry size", "incorrect");
ok(memcmp(entry.ptr, payload, max_size) == 0,
"0 is expected");
rc = prbuf_iterator_next(&iter, &entry);
ok(rc == -1, "rc is %d", rc);
p = prbuf_prepare(&buf, max_size + 1);
ok(p == NULL, "NULL is expected");
footer();
}
/**
* There are three possible configurations of test:
* 1. The size of buffer;
......@@ -337,7 +390,7 @@ test_buffer_prepared_large(void)
int
main(void)
{
plan(39);
plan(45);
payload_large_init();
test_buffer_foreach_size();
test_buffer_bad_version();
......@@ -347,5 +400,6 @@ main(void)
test_buffer_empty();
test_buffer_prepared();
test_buffer_prepared_large();
test_max_record_size();
return check_plan();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment