/*- * Public Domain 2014-2020 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" #include static const char *const uri = "table:large"; #define DATASIZE (1024 * 1024) #define MODIFY_COUNT (1024) #define NUM_DOCS 2 static void on_alarm(int) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void on_alarm(int signo) { (void)signo; /* Unused parameter */ fprintf(stderr, "cursor->modify timed out \n"); abort(); /* NOTREACHED */ } static int ignore_errors = 0; static int handle_error(WT_EVENT_HANDLER *handler, WT_SESSION *session, int error, const char *message) { (void)(handler); /* Skip the error messages we're expecting to see. */ if (ignore_errors > 0 && (strstr(message, "requires key be set") != NULL || strstr(message, "requires value be set") != NULL)) { --ignore_errors; return (0); } (void)fprintf(stderr, "%s: %s\n", message, session->strerror(session, error)); return (0); } static WT_EVENT_HANDLER event_handler = {handle_error, NULL, NULL, NULL}; int main(int argc, char *argv[]) { TEST_OPTS *opts, _opts; WT_CURSOR *c; WT_ITEM value; WT_MODIFY modify_entry; WT_SESSION *session, *session2; uint64_t i, j, offset; char *large_doc; opts = &_opts; memset(opts, 0, sizeof(*opts)); testutil_check(testutil_parse_opts(argc, argv, opts)); testutil_make_work_dir(opts->home); testutil_check(wiredtiger_open(opts->home, &event_handler, "create,cache_size=1G,statistics_log=(json,wait=1)", &opts->conn)); testutil_check(opts->conn->open_session(opts->conn, NULL, NULL, &session)); testutil_check(session->create(session, uri, "key_format=Q,value_format=u,leaf_item_max=64M,leaf_page_max=32k,memory_page_max=1M")); testutil_check(session->open_cursor(session, uri, NULL, NULL, &c)); /* Value is initialized with 'v' and has not significance to it. */ large_doc = dmalloc(DATASIZE); memset(large_doc, 'v', DATASIZE); value.data = large_doc; value.size = DATASIZE; /* Insert records. */ for (i = 0; i < NUM_DOCS; i++) { c->set_key(c, i); c->set_value(c, &value); testutil_check(c->insert(c)); } testutil_check(c->close(c)); if (opts->verbose) printf("%d documents inserted\n", NUM_DOCS); /* Setup Transaction to pin the cache */ testutil_check(session->begin_transaction(session, "isolation=snapshot")); /* Set an alarm so we can debug hangs. */ (void)signal(SIGALRM, on_alarm); /* Start another session to perform small updates. */ testutil_check(opts->conn->open_session(opts->conn, NULL, NULL, &session2)); testutil_check(session2->open_cursor(session2, uri, NULL, NULL, &c)); j = offset = 0; while (++j < MODIFY_COUNT) { for (i = 0; i < NUM_DOCS; i++) { /* Position the cursor. */ testutil_check(session2->begin_transaction(session2, "isolation=snapshot")); c->set_key(c, i); modify_entry.data.data = "abcdefghijklmnopqrstuvwxyz"; modify_entry.data.size = strlen(modify_entry.data.data); modify_entry.offset = offset; modify_entry.size = modify_entry.data.size; /* FIXME-WT-6113: extend timeout to pass the test */ (void)alarm(15); testutil_check(c->modify(c, &modify_entry, 1)); (void)alarm(0); testutil_check(session2->commit_transaction(session2, NULL)); } /* * Modify operations are done similar to append sequence. This has no bearing on the test * outcome. */ offset += modify_entry.data.size; offset = offset < DATASIZE ? offset : 0; if (opts->verbose) printf("modify count %" PRIu64 "\n", j * NUM_DOCS); } free(large_doc); testutil_cleanup(opts); return (EXIT_SUCCESS); }