Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
ibuf: copy ibuf.[ch] into module's code
Just copy and change includes. It is necessary to change function names
in a next commit.

The source is the small version, which is bundled into the module:
1.1-63-g3df5050.

Part of #59
  • Loading branch information
Totktonada committed Apr 7, 2022
commit a68a35e6e42b0bda7027ebe16057ea0d2ba4d36e
1 change: 1 addition & 0 deletions memcached/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ add_library(internalso SHARED
"internal/expiration.c"
"internal/memcached.c"
"internal/mc_sasl.c"
"${CMAKE_SOURCE_DIR}/third_party/memcached_ibuf.c"
)

target_link_libraries(internalso msgpuck)
Expand Down
2 changes: 1 addition & 1 deletion memcached/internal/memcached.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
#include <stdbool.h>

#include <tarantool/module.h>
#include <small/ibuf.h>
#include <small/obuf.h>

#include "alloc.h"
#include "memcached.h"
#include "memcached_ibuf.h"
#include "memcached_layer.h"
#include "error.h"
#include "network.h"
Expand Down
2 changes: 1 addition & 1 deletion memcached/internal/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@

#include <tarantool/module.h>
#include <small/mempool.h>
#include <small/ibuf.h>
#include <small/obuf.h>

#include "alloc.h"
#include "memcached.h"
#include "memcached_ibuf.h"
#include "constants.h"
#include "network.h"

Expand Down
2 changes: 1 addition & 1 deletion memcached/internal/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#define TIMEOUT_INFINITY 365*86400*100.0

#include <small/ibuf.h>
#include "memcached_ibuf.h"

size_t
mnet_writev(int fd, struct iovec *iov, int iovcnt, size_t size_hint);
Expand Down
2 changes: 1 addition & 1 deletion memcached/internal/proto_bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "memcached_layer.h"
#include "mc_sasl.h"

#include <small/ibuf.h>
#include "memcached_ibuf.h"
#include <small/obuf.h>

static inline int
Expand Down
2 changes: 1 addition & 1 deletion memcached/internal/proto_txt.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

#include <tarantool/module.h>
#include <msgpuck.h>
#include <small/ibuf.h>
#include <small/obuf.h>

#include "memcached.h"
#include "memcached_ibuf.h"
#include "constants.h"
#include "memcached_layer.h"
#include "error.h"
Expand Down
106 changes: 106 additions & 0 deletions third_party/memcached_ibuf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright 2010-2016, Tarantool AUTHORS, please see AUTHORS file.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "memcached_ibuf.h"
#include <string.h>
#include <small/slab_cache.h>

/** Initialize an input buffer. */
void
ibuf_create(struct ibuf *ibuf, struct slab_cache *slabc, size_t start_capacity)
{
ibuf->slabc = slabc;
ibuf->buf = ibuf->rpos = ibuf->wpos = ibuf->end = NULL;
ibuf->start_capacity = start_capacity;
/* Don't allocate the buffer yet. */
}

void
ibuf_destroy(struct ibuf *ibuf)
{
if (ibuf->buf) {
struct slab *slab = slab_from_data(ibuf->buf);
slab_put(ibuf->slabc, slab);
}
}

/** Free memory allocated by this buffer */
void
ibuf_reinit(struct ibuf *ibuf)
{
struct slab_cache *slabc = ibuf->slabc;
size_t start_capacity = ibuf->start_capacity;
ibuf_destroy(ibuf);
ibuf_create(ibuf, slabc, start_capacity);
}

/**
* Ensure the buffer has sufficient capacity
* to store size bytes, and return pointer to
* the beginning.
*/
void *
ibuf_reserve_slow(struct ibuf *ibuf, size_t size)
{
assert(ibuf->wpos + size > ibuf->end);
size_t used = ibuf_used(ibuf);
size_t capacity = ibuf_capacity(ibuf);
/*
* Check if we have enough space in the
* current buffer. In this case de-fragment it
* by moving existing data to the beginning.
* Otherwise, get a bigger buffer.
*/
if (size + used <= capacity) {
memmove(ibuf->buf, ibuf->rpos, used);
} else {
/* Use iobuf_readahead as allocation factor. */
size_t new_capacity = capacity * 2;
if (new_capacity < ibuf->start_capacity)
new_capacity = ibuf->start_capacity;

while (new_capacity < used + size)
new_capacity *= 2;

struct slab *slab = slab_get(ibuf->slabc, new_capacity);
if (slab == NULL)
return NULL;
char *ptr = (char *) slab_data(slab);
memcpy(ptr, ibuf->rpos, used);
if (ibuf->buf)
slab_put(ibuf->slabc, slab_from_data(ibuf->buf));
ibuf->buf = ptr;
ibuf->end = ibuf->buf + slab_capacity(slab);
}
ibuf->rpos = ibuf->buf;
ibuf->wpos = ibuf->rpos + used;
return ibuf->wpos;
}

206 changes: 206 additions & 0 deletions third_party/memcached_ibuf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#ifndef TARANTOOL_SMALL_IBUF_H_INCLUDED
#define TARANTOOL_SMALL_IBUF_H_INCLUDED
/*
* Copyright 2010-2016, Tarantool AUTHORS, please see AUTHORS file.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stddef.h>
#include <assert.h>

#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */

/** @module Input buffer. */

struct slab_cache;

/*
* Continuous piece of memory to store input.
* Allocated in factors of 'start_capacity'.
* Maintains position of the data "to be processed".
*
* Typical use case:
*
* struct ibuf *in;
* coio_bread(coio, in, request_len);
* if (ibuf_size(in) >= request_len) {
* process_request(in->rpos, request_len);
* in->rpos += request_len;
* }
*/
struct ibuf
{
struct slab_cache *slabc;
char *buf;
/** Start of input. */
char *rpos;
/** End of useful input */
char *wpos;
/** End of buffer. */
char *end;
size_t start_capacity;
};

void
ibuf_create(struct ibuf *ibuf, struct slab_cache *slabc, size_t start_capacity);

void
ibuf_destroy(struct ibuf *ibuf);

void
ibuf_reinit(struct ibuf *ibuf);

/** How much data is read and is not parsed yet. */
static inline size_t
ibuf_used(struct ibuf *ibuf)
{
assert(ibuf->wpos >= ibuf->rpos);
return ibuf->wpos - ibuf->rpos;
}

/** How much data can we fit beyond buf->wpos */
static inline size_t
ibuf_unused(struct ibuf *ibuf)
{
assert(ibuf->wpos <= ibuf->end);
return ibuf->end - ibuf->wpos;
}

/** How much memory is allocated */
static inline size_t
ibuf_capacity(struct ibuf *ibuf)
{
return ibuf->end - ibuf->buf;
}

/**
* Integer value of the position in the buffer - stable
* in case of realloc.
*/
static inline size_t
ibuf_pos(struct ibuf *ibuf)
{
assert(ibuf->buf <= ibuf->rpos);
return ibuf->rpos - ibuf->buf;
}

/** Forget all cached input. */
static inline void
ibuf_reset(struct ibuf *ibuf)
{
ibuf->rpos = ibuf->wpos = ibuf->buf;
}

void *
ibuf_reserve_slow(struct ibuf *ibuf, size_t size);

static inline void *
ibuf_reserve(struct ibuf *ibuf, size_t size)
{
if (ibuf->wpos + size <= ibuf->end)
return ibuf->wpos;
return ibuf_reserve_slow(ibuf, size);
}

static inline void *
ibuf_alloc(struct ibuf *ibuf, size_t size)
{
void *ptr;
if (ibuf->wpos + size <= ibuf->end)
ptr = ibuf->wpos;
else {
ptr = ibuf_reserve_slow(ibuf, size);
if (ptr == NULL)
return NULL;
}
ibuf->wpos += size;
return ptr;
}

static inline void *
ibuf_reserve_cb(void *ctx, size_t *size)
{
struct ibuf *buf = (struct ibuf *) ctx;
void *p = ibuf_reserve(buf, *size ? *size : buf->start_capacity);
*size = ibuf_unused(buf);
return p;
}

static inline void *
ibuf_alloc_cb(void *ctx, size_t size)
{
return ibuf_alloc((struct ibuf *) ctx, size);
}

#if defined(__cplusplus)
} /* extern "C" */

#include "exception.h"

/** Reserve space for sz bytes in the input buffer. */
static inline void *
ibuf_reserve_xc(struct ibuf *ibuf, size_t size)
{
void *ptr = ibuf_reserve(ibuf, size);
if (ptr == NULL)
tnt_raise(OutOfMemory, size, "ibuf", "reserve");
return ptr;
}

static inline void *
ibuf_alloc_xc(struct ibuf *ibuf, size_t size)
{
void *ptr = ibuf_alloc(ibuf, size);
if (ptr == NULL)
tnt_raise(OutOfMemory, size, "ibuf", "alloc");
return ptr;
}

static inline void *
ibuf_reserve_xc_cb(void *ctx, size_t *size)
{
void *ptr = ibuf_reserve_cb(ctx, size);
if (ptr == NULL)
tnt_raise(OutOfMemory, *size, "ibuf", "reserve");
return ptr;
}

static inline void *
ibuf_alloc_xc_cb(void *ctx, size_t size)
{
void *ptr = ibuf_alloc_cb(ctx, size);
if (ptr == NULL)
tnt_raise(OutOfMemory, size, "ibuf", "alloc");
return ptr;
}

#endif /* defined(__cplusplus) */

#endif /* TARANTOOL_SMALL_IBUF_H_INCLUDED */