summaryrefslogtreecommitdiff
path: root/src/include/buf.i
blob: 17f67afefce344db2aa97362cce2482d88f0d013 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*-
 * Copyright (c) 2014-2017 MongoDB, Inc.
 * Copyright (c) 2008-2014 WiredTiger, Inc.
 *	All rights reserved.
 *
 * See the file LICENSE for redistribution information.
 */

/*
 * __wt_buf_grow --
 *	Grow a buffer that may be in-use, and ensure that all data is local to
 * the buffer.
 */
static inline int
__wt_buf_grow(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size)
{
	return (size > buf->memsize || !WT_DATA_IN_ITEM(buf) ?
	    __wt_buf_grow_worker(session, buf, size) : 0);
}

/*
 * __wt_buf_extend --
 *	Grow a buffer that's currently in-use.
 */
static inline int
__wt_buf_extend(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size)
{
	/*
	 * The difference between __wt_buf_grow and __wt_buf_extend is that the
	 * latter is expected to be called repeatedly for the same buffer, and
	 * so grows the buffer exponentially to avoid repeated costly calls to
	 * realloc.
	 */
	return (size > buf->memsize ?
	    __wt_buf_grow(session, buf, WT_MAX(size, 2 * buf->memsize)) : 0);
}

/*
 * __wt_buf_init --
 *	Create an empty buffer at a specific size.
 */
static inline int
__wt_buf_init(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size)
{
	/*
	 * The buffer grow function does what we need, but anticipates data
	 * referenced by the buffer. Avoid any data copy by setting data to
	 * reference the buffer's allocated memory, and clearing it.
	 */
	buf->data = buf->mem;
	buf->size = 0;
	return (__wt_buf_grow(session, buf, size));
}

/*
 * __wt_buf_initsize --
 *	Create an empty buffer at a specific size, and set the data length.
 */
static inline int
__wt_buf_initsize(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size)
{
	WT_RET(__wt_buf_init(session, buf, size));

	buf->size = size;			/* Set the data length. */

	return (0);
}

/*
 * __wt_buf_set --
 *	Set the contents of the buffer.
 */
static inline int
__wt_buf_set(
    WT_SESSION_IMPL *session, WT_ITEM *buf, const void *data, size_t size)
{
	/*
	 * The buffer grow function does what we need, but expects the data to
	 * be referenced by the buffer. If we're copying data from outside the
	 * buffer, set it up so it makes sense to the buffer grow function. (No
	 * test needed, this works if WT_ITEM.data is already set to "data".)
	 */
	buf->data = data;
	buf->size = size;
	return (__wt_buf_grow(session, buf, size));
}

/*
 * __wt_buf_setstr --
 *	Set the contents of the buffer to a NUL-terminated string.
 */
static inline int
__wt_buf_setstr(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *s)
{
	return (__wt_buf_set(session, buf, s, strlen(s) + 1));
}

/*
 * __wt_buf_free --
 *	Free a buffer.
 */
static inline void
__wt_buf_free(WT_SESSION_IMPL *session, WT_ITEM *buf)
{
	__wt_free(session, buf->mem);

	memset(buf, 0, sizeof(WT_ITEM));
}

/*
 * __wt_scr_free --
 *	Release a scratch buffer.
 */
static inline void
__wt_scr_free(WT_SESSION_IMPL *session, WT_ITEM **bufp)
{
	WT_ITEM *buf;

	if ((buf = *bufp) != NULL) {
		*bufp = NULL;

		if (session->scratch_cached + buf->memsize >=
		    S2C(session)->session_scratch_max) {
			__wt_free(session, buf->mem);
			buf->memsize = 0;
		} else
			session->scratch_cached += buf->memsize;

		buf->data = NULL;
		buf->size = 0;
		F_CLR(buf, WT_ITEM_INUSE);
	}
}