diff options
author | Keith Bostic <keith.bostic@wiredtiger.com> | 2012-01-12 16:33:26 +0000 |
---|---|---|
committer | Keith Bostic <keith.bostic@wiredtiger.com> | 2012-01-12 16:33:26 +0000 |
commit | 933cadcb3499d4014c2cd47c2e6801b3517e08bf (patch) | |
tree | ec254830cb45781a47f918ed7d634cca4d70ef81 /src/support | |
parent | f03c0f181f94923cb275f73d4110a1f3633b915b (diff) | |
download | mongo-933cadcb3499d4014c2cd47c2e6801b3517e08bf.tar.gz |
Remove session buffer support: they are no longer used for bulk-load and they
tended to tie down too much memory for long periods, in Sesame's workloads.
--HG--
extra : rebase_source : 0e038d8ece0ed6ee929eacac4e3af8bb6fe4586a
Diffstat (limited to 'src/support')
-rw-r--r-- | src/support/err.c | 11 | ||||
-rw-r--r-- | src/support/pow.c | 2 | ||||
-rw-r--r-- | src/support/sess_buf.c | 229 |
3 files changed, 2 insertions, 240 deletions
diff --git a/src/support/err.c b/src/support/err.c index eb5ec59b7ca..18454629d32 100644 --- a/src/support/err.c +++ b/src/support/err.c @@ -176,17 +176,6 @@ __wt_illegal_value(WT_SESSION_IMPL *session) } /* - * __wt_file_item_too_big -- - * Print a standard error message when an element is too large to store. - */ -int -__wt_file_item_too_big(WT_SESSION_IMPL *session) -{ - WT_RET_MSG(session, WT_ERROR, - "the item is too large for the file to store"); -} - -/* * __wt_unknown_object_type -- * Print a standard error message when given an unknown object type. */ diff --git a/src/support/pow.c b/src/support/pow.c index 33b58d8b46c..5b73ec11d08 100644 --- a/src/support/pow.c +++ b/src/support/pow.c @@ -7,6 +7,7 @@ #include "wt_internal.h" +#ifdef __WIREDTIGER_UNUSED__ /* * __wt_nlpo2_round -- * Round up to the next-largest power-of-two for a 32-bit unsigned value. @@ -52,6 +53,7 @@ __wt_nlpo2(uint32_t v) v |= v >> 16; return (v + 1); } +#endif /* __WIREDTIGER_UNUSED__ */ /* * __wt_ispo2 -- diff --git a/src/support/sess_buf.c b/src/support/sess_buf.c deleted file mode 100644 index bd7e109cb70..00000000000 --- a/src/support/sess_buf.c +++ /dev/null @@ -1,229 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2008-2011 WiredTiger, Inc. - * All rights reserved. - */ - -#include "wt_internal.h" - -/* - * __wt_sb_alloc -- - * Allocate memory from the WT_SESSION_IMPL's buffer and fill it in. - */ -int -__wt_sb_alloc( - WT_SESSION_IMPL *session, size_t size, void *retp, WT_SESSION_BUFFER **sbp) -{ -#ifndef HAVE_SESSION_BUFFERS - *sbp = NULL; - return (__wt_calloc(session, 1, size, retp)); -#else - WT_SESSION_BUFFER *sb; - size_t alloc_size; - uint32_t align_size; - int single_use; - - /* - * Allocate memory for an insert or change; there's a buffer in the - * WT_SESSION_IMPL structure for allocation of chunks of memory to hold - * changed or inserted values. - * - * We align allocations because we directly access WT_UPDATE structure - * fields in the memory (the x86 handles unaligned accesses, but I don't - * want to have to find and fix this code for a port to a system that - * doesn't handle unaligned accesses). It wastes space, but this memory - * is never written to disk and there are fewer concerns about memory - * than with on-disk structures. Any other code allocating memory from - * this buffer needs to align its allocations as well. - * - * The first thing in each chunk of memory is a WT_SESSION_BUFFER - * structure (check to be a multiple of 4B during initialization); - * then one or more WT_UPDATE structure plus value chunk pairs. - * - * Figure out how much space we need: this code limits the maximum size - * of a data item stored in the file. In summary, for a big item we - * have to store a WT_SESSION_BUFFER structure, the WT_UPDATE structure - * and the data, all in an allocated buffer. We only pass a 32-bit - * value to our allocation routine, so we can't store an item bigger - * than the maximum 32-bit value minus the sizes of those two - * structures, where the WT_UPDATE structure and data item are aligned - * to a 32-bit boundary. We could fix this, but it's unclear it's - * worth the effort: document you can store a (4GB - 512B) item max, - * it's insane to store 4GB items in the file anyway. - */ - if (size > WT_BTREE_OBJECT_SIZE_MAX) - return (__wt_file_item_too_big(session)); - align_size = WT_ALIGN(size + sizeof(WT_UPDATE), sizeof(uint32_t)); - - /* If we already have a buffer and the data fits, we're done. */ - sb = session->sb; - if (sb != NULL && align_size <= sb->space_avail) - goto no_allocation; - - /* - * We start by allocating 4KB for the thread, then every time we have - * to re-allocate the buffer, we double the allocation size, up to a - * total of 8MB, so any thread doing a lot of updates won't re-allocate - * new chunks of memory that often. - */ - if (session->update_alloc_size == 0) { - /* - * 2KB is correct, we're going to double it to 4KB when we - * calculate a new allocation size. - */ - session->update_alloc_size = 2 * 1024; - - /* - * We don't want to never aggregate changes because records are - * initially relatively large, compared to the allocation size, - * that is, if the application is loading many 4KB records, we'd - * like to handle that reasonably. This code adjusts for that - * case. - * - * If we get nothing but 256KB inserts, this code will allocate - * each of them individually, without aggregation, never growing - * the aggregation buffer size. That doesn't seem all that bad, - * aggregation isn't intended for lots of large records, rather - * it's intended for lots of small records. - */ - if (align_size > session->update_alloc_size && - align_size < 128 * 1024) - session->update_alloc_size = 128 * 1024; - } - - /* - * Decide how much memory to allocate: if it's a one-off (that is, the - * value is bigger than anything we'll aggregate into these buffers), - * allocate just enough memory. Else, allocate the next power-of-two - * larger, up to 8MB. - */ - if (align_size > session->update_alloc_size) { - alloc_size = sizeof(WT_SESSION_BUFFER) + align_size; - single_use = 1; - } else { - if (session->update_alloc_size < 8 * WT_MEGABYTE) - session->update_alloc_size = - __wt_nlpo2(session->update_alloc_size); - alloc_size = session->update_alloc_size; - single_use = 0; - } - - WT_RET(__wt_calloc(session, 1, alloc_size, &sb)); - sb->len = WT_STORE_SIZE(alloc_size); - sb->space_avail = WT_STORE_SIZE(alloc_size - sizeof(WT_SESSION_BUFFER)); - sb->first_free = (uint8_t *)sb + sizeof(WT_SESSION_BUFFER); - - /* - * If it's a single use allocation, ignore any current buffer in the - * session; else, release the old session buffer and replace it with - * the new one. - */ - if (!single_use) { - /* - * The "in" reference count is artificially incremented by 1 as - * long as a session buffer is referenced by the session - * handle; we do not want session buffers freed because a page - * was evicted and the count went to 0 while the buffer might - * still be used for future K/V inserts or modifications. - */ - if (session->sb != NULL) - __wt_sb_decrement(session, session->sb, NULL); - session->sb = sb; - - sb->in = 1; - } - -no_allocation: - *(void **)retp = sb->first_free; - *sbp = sb; - - sb->first_free += align_size; - sb->space_avail -= align_size; - ++sb->in; - WT_ASSERT(session, sb->in != 0); - - return (0); -#endif -} - -/* - * __wt_sb_free -- - * Free a chunk of memory from a per-WT_SESSION_IMPL buffer. - */ -void -__wt_sb_free(WT_SESSION_IMPL *session, WT_SESSION_BUFFER *sb, void *p) -{ -#ifndef HAVE_SESSION_BUFFERS - WT_UNUSED(sb); - - __wt_free(session, p); -#else - WT_UNUSED(p); - - WT_ASSERT(session, sb->out < sb->in); - - if (++sb->out == sb->in) - __wt_free(session, sb); -#endif -} - -/* - * __wt_sb_decrement -- - * Decrement the "insert" value of a per-WT_SESSION_IMPL buffer. - */ -void -__wt_sb_decrement(WT_SESSION_IMPL *session, WT_SESSION_BUFFER *sb, void *p) -{ -#ifndef HAVE_SESSION_BUFFERS - WT_UNUSED(sb); - - __wt_free(session, p); -#else - WT_UNUSED(p); - - WT_ASSERT(session, sb->out < sb->in); - - /* - * This function is used for two reasons. - * - * #1: it's possible we allocated memory from the session buffer, but - * then an error occurred. In this case we don't try and clean up the - * session buffer, it's simpler to decrement the counters and pretend - * the memory is no longer in use. We're still in the allocation path - * so we decrement the "in" field instead of incrementing the "out" - * field, if the eviction thread were to update the "out" field at the - * same time, we could race. - * - * #2: the "in" reference count is artificially incremented by 1 as - * long as a session buffer is referenced by the session handle; we do - * not want session buffers freed because a page was evicted and the - * count went to 0 while the buffer might still be used for future K/V - * inserts or modifications. - */ - --sb->in; - - /* - * In the above case #1, if the session buffer was a one-off (allocated - * for a single use), we have to free it here, it's not linked to any - * WT_PAGE in the system. - * - * In the above case #2, our artificial increment might be the last - * reference, if all of the WT_PAGE's referencing this buffer have been - * reconciled since the K/V inserts or modifications. - * - * In both of these cases, sb->in == sb->out, and we need to free the - * buffer. - * - * XXX - * There's a race here in the above case #2: if this code, and the page - * discard code race, it's possible neither will realize the buffer is - * no longer needed and free it. The fix is to involve the eviction - * thread: it may need a linked list of buffers they review to ensure - * it never happens. I'm living with this now: it's an unlikely - * race, and it's a memory leak if it ever happens. - */ - if (sb->in == sb->out) - __wt_free(session, sb); -#endif -} |