diff options
Diffstat (limited to 'src/third_party/wiredtiger/test/utility/modify.c')
-rw-r--r-- | src/third_party/wiredtiger/test/utility/modify.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/third_party/wiredtiger/test/utility/modify.c b/src/third_party/wiredtiger/test/utility/modify.c new file mode 100644 index 00000000000..254dd58e3b4 --- /dev/null +++ b/src/third_party/wiredtiger/test/utility/modify.c @@ -0,0 +1,115 @@ +/*- + * Public Domain 2014-present MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "test_util.h" + +/* + * testutil_modify_apply -- + * Implement a modify using a completely separate algorithm as a check on the internal library + * algorithms. + */ +void +testutil_modify_apply(WT_ITEM *value, WT_ITEM *workspace, WT_MODIFY *entries, int nentries) +{ + WT_ITEM *ta, *tb, *tmp, _tmp; + size_t len, size; + int i; + + /* + * Passed a value and array of modifications, plus a temporary buffer for an additional work + * space. + * + * Process the entries to figure out the largest possible buffer we need. This is pessimistic + * because we're ignoring replacement bytes, but it's a simpler calculation. + */ + for (size = value->size, i = 0; i < nentries; ++i) { + if (entries[i].offset >= size) + size = entries[i].offset; + size += entries[i].data.size; + } + + /* Grow the buffers. */ + testutil_check(__wt_buf_grow(NULL, value, size)); + testutil_check(__wt_buf_grow(NULL, workspace, size)); + + /* + * Overwrite anything not initialized in the original buffer, and overwrite the entire workspace + * buffer. + */ + if ((value->memsize - value->size) > 0) + memset((uint8_t *)value->mem + value->size, 0xff, value->memsize - value->size); + if (workspace->memsize > 0) + memset((uint8_t *)workspace->mem, 0xff, workspace->memsize); + + ta = value; + tb = workspace; + + /* + * From the starting buffer, create a new buffer b based on changes in the entries array. We're + * doing a brute force solution here to test the faster solution implemented in the library. + */ + for (i = 0; i < nentries; ++i) { + /* Take leading bytes from the original, plus any gap bytes. */ + if (entries[i].offset >= ta->size) { + memcpy(tb->mem, ta->mem, ta->size); + if (entries[i].offset > ta->size) + memset((uint8_t *)tb->mem + ta->size, '\0', entries[i].offset - ta->size); + } else if (entries[i].offset > 0) + memcpy(tb->mem, ta->mem, entries[i].offset); + tb->size = entries[i].offset; + + /* Take replacement bytes. */ + if (entries[i].data.size > 0) { + memcpy((uint8_t *)tb->mem + tb->size, entries[i].data.data, entries[i].data.size); + tb->size += entries[i].data.size; + } + + /* Take trailing bytes from the original. */ + len = entries[i].offset + entries[i].size; + if (ta->size > len) { + memcpy((uint8_t *)tb->mem + tb->size, (uint8_t *)ta->mem + len, ta->size - len); + tb->size += ta->size - len; + } + testutil_assert(tb->size <= size); + + /* Swap the buffers and do it again. */ + tmp = ta; + ta = tb; + tb = tmp; + } + ta->data = ta->mem; + tb->data = tb->mem; + + /* + * The final results may not be in the original buffer, in which case we swap them back around. + */ + if (ta != value) { + _tmp = *ta; + *ta = *tb; + *tb = _tmp; + } +} |