/* * sophia database * sphia.org * * Copyright (c) Dmitry Simonenko * BSD License */ #include #include "test.h" static char *dbrep = "./rep"; static inline int cmp(char *a, size_t asz, char *b, size_t bsz, void *arg) { register uint32_t av = *(uint32_t*)a; register uint32_t bv = *(uint32_t*)b; if (av == bv) return 0; return (av > bv) ? 1 : -1; } static void merge_liveonly(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( exists(dbrep, 1, "log.incomplete") == 1 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); t( exists(dbrep, 1, "log.incomplete") == 0 ); t( exists(dbrep, 1, "log") == 0 ); t( exists(dbrep, 1, "db") == 0 ); t( exists(dbrep, 1, "db.incomplete") == 0 ); t( exists(dbrep, 2, "log.incomplete") == 1 ); t( exists(dbrep, 2, "log") == 0 ); t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "log") == 0 ); t( exists(dbrep, 2, "log") == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_phase0(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( exists(dbrep, 1, "log.incomplete") == 1 ); uint32_t k = 1, v = 1; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); k = 2; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); k = 3; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); t( exists(dbrep, 1, "log.incomplete") == 0 ); t( exists(dbrep, 1, "log") == 0 ); t( exists(dbrep, 1, "db.incomplete") == 0 ); t( exists(dbrep, 1, "db") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 1 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "log.incomplete") == 0 ); t( exists(dbrep, 1, "log") == 0 ); t( exists(dbrep, 1, "db.incomplete") == 0 ); t( exists(dbrep, 1, "db") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 0 ); t( exists(dbrep, 2, "log") == 0 ); t( exists(dbrep, 2, "db") == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_phase1(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( exists(dbrep, 1, "log.incomplete") == 1 ); uint32_t k = 1, v = 1; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); k = 2; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); k = 3; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); t( exists(dbrep, 1, "log.incomplete") == 0 ); t( exists(dbrep, 1, "log") == 0 ); t( exists(dbrep, 1, "db.incomplete") == 0 ); t( exists(dbrep, 1, "db") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 1 ); t( exists(dbrep, 2, "log") == 0 ); k = 4; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); k = 5; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); k = 6; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); t( exists(dbrep, 1, "db") == 1 ); t( exists(dbrep, 2, "db.incomplete") == 0 ); t( exists(dbrep, 2, "db") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 0 ); t( exists(dbrep, 2, "log") == 0 ); t( exists(dbrep, 3, "log.incomplete") == 1 ); t( exists(dbrep, 3, "log") == 0 ); t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "db") == 1 ); t( exists(dbrep, 2, "db.incomplete") == 0 ); t( exists(dbrep, 2, "db") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 0 ); t( exists(dbrep, 2, "log") == 0 ); t( exists(dbrep, 3, "log.incomplete") == 0 ); t( exists(dbrep, 3, "log") == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_phase1gc(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 1) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( exists(dbrep, 1, "log.incomplete") == 1 ); uint32_t k = 1, v = 1; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); k = 2; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); k = 3; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); t( exists(dbrep, 1, "log.incomplete") == 0 ); t( exists(dbrep, 1, "log") == 0 ); t( exists(dbrep, 1, "db.incomplete") == 0 ); t( exists(dbrep, 1, "db") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 1 ); t( exists(dbrep, 2, "log") == 0 ); k = 4; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); k = 5; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); k = 6; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); t( exists(dbrep, 1, "db") == 0 ); t( exists(dbrep, 2, "db.incomplete") == 0 ); t( exists(dbrep, 2, "db") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 0 ); t( exists(dbrep, 2, "log") == 0 ); t( exists(dbrep, 3, "log.incomplete") == 1 ); t( exists(dbrep, 3, "log") == 0 ); t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "db") == 0 ); t( exists(dbrep, 2, "db.incomplete") == 0 ); t( exists(dbrep, 2, "db") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 0 ); t( exists(dbrep, 2, "log") == 0 ); t( exists(dbrep, 3, "log.incomplete") == 0 ); t( exists(dbrep, 3, "log") == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_phase1n(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); uint32_t k = 1, v = 1; /* 1 */ t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); /* 2 */ t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); /* 3 */ t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); /* 4 */ t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); /* 5 */ t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); /* merge */ t( exists(dbrep, 1, "db") == 1 ); t( exists(dbrep, 2, "db") == 1 ); t( exists(dbrep, 3, "db") == 1 ); t( exists(dbrep, 4, "db") == 1 ); t( exists(dbrep, 5, "db") == 1 ); t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_phase1ngc(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 1) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); uint32_t k = 1, v = 1; /* 1 */ t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); /* 2 */ t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); /* 3 */ t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); /* 4 */ t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); /* 5 */ t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); /* merge */ t( exists(dbrep, 1, "db") == 0 ); t( exists(dbrep, 2, "db") == 0 ); t( exists(dbrep, 3, "db") == 0 ); t( exists(dbrep, 4, "db") == 0 ); t( exists(dbrep, 5, "db") == 1 ); t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_delete(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 0, v = 1; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); k = 1; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "log") == 1 ); t( exists(dbrep, 1, "log.incomplete") == 0 ); db = sp_open(env); t( db != NULL ); k = 0; t( sp_delete(db, &k, sizeof(k)) == 0 ); k = 1; t( sp_delete(db, &k, sizeof(k)) == 0 ); t( exists(dbrep, 1, "log") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 1 ); t( exists(dbrep, 2, "log") == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0); t( exists(dbrep, 1, "log") == 0 ); t( exists(dbrep, 2, "log.incomplete") == 0 ); t( exists(dbrep, 2, "log") == 0 ); t( exists(dbrep, 3, "log.incomplete") == 1 ); t( exists(dbrep, 1, "db") == 0 ); t( exists(dbrep, 2, "db") == 0 ); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; size_t vsize = 0; void *vp = NULL; t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 0 ); k = 1; vsize = 0; vp = NULL; t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 0 ); t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_deletegc(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 1) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 0, v = 1; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); k = 1; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "log") == 1 ); t( exists(dbrep, 1, "log.incomplete") == 0 ); db = sp_open(env); t( db != NULL ); k = 0; t( sp_delete(db, &k, sizeof(k)) == 0 ); k = 1; t( sp_delete(db, &k, sizeof(k)) == 0 ); t( exists(dbrep, 1, "log") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 1 ); t( exists(dbrep, 2, "log") == 0 ); t( sp_ctl(db, SPMERGEFORCE) == 0 ); t( exists(dbrep, 1, "log") == 0 ); t( exists(dbrep, 2, "log.incomplete") == 0 ); t( exists(dbrep, 2, "log") == 0 ); t( exists(dbrep, 1, "db") == 0 ); t( exists(dbrep, 2, "db") == 0 ); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; size_t vsize = 0; void *vp = NULL; t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 0 ); k = 1; vsize = 0; vp = NULL; t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 0 ); t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_delete_log_n(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 0, v = 1; while (k < 12) { t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); k++; } t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "log") == 1 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { t( sp_delete(db, &k, sizeof(k)) == 0); k++; } t( exists(dbrep, 1, "log.incomplete") == 0 ); t( exists(dbrep, 1, "log") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 1 ); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { size_t vsize = 0; void *vp = NULL; t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 0 ); k++; } t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "log") == 1 ); t( exists(dbrep, 2, "log") == 1 ); t( exists(dbrep, 3, "log") == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_delete_page_n(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 0, v = 1; while (k < 12) { t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); k++; } t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "log") == 1 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { t( sp_delete(db, &k, sizeof(k)) == 0); k++; } t( exists(dbrep, 1, "log") == 1 ); t( exists(dbrep, 2, "log.incomplete") == 1 ); t( sp_ctl(db, SPMERGEFORCE) == 0); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { size_t vsize = 0; void *vp = NULL; t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 0 ); k++; } t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "log") == 0 ); t( exists(dbrep, 2, "log") == 0 ); t( exists(dbrep, 2, "db") == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_delete_page_log_n(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 0, v = 1; while (k < 12) { t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); k++; } t( sp_ctl(db, SPMERGEFORCE) == 0); t( exists(dbrep, 1, "db") == 1 ); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { t( sp_delete(db, &k, sizeof(k)) == 0); k++; } t( sp_ctl(db, SPMERGEFORCE) == 0); t( exists(dbrep, 2, "log.incomplete") == 0 ); t( exists(dbrep, 2, "db") == 1 ); t( exists(dbrep, 3, "log.incomplete") == 1 ); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { size_t vsize = 0; void *vp = NULL; t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 0 ); k++; } t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "db") == 1 ); t( exists(dbrep, 2, "db") == 1 ); t( exists(dbrep, 3, "log") == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_delete_page_log_n_even(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 0, v = 1; while (k < 12) { v = k; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); k++; } t( sp_ctl(db, SPMERGEFORCE) == 0); t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "db") == 1 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { if (k > 0 && (k % 2) == 0) t( sp_delete(db, &k, sizeof(k)) == 0); k++; } t( exists(dbrep, 2, "log.incomplete") == 1 ); t( sp_ctl(db, SPMERGEFORCE) == 0); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { size_t vsize = 0; void *vp = NULL; if (k == 0 || (k % 2) != 0) { t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 1 ); t( vsize == sizeof(v) ); t( *(uint32_t*)vp == k ); free(vp); } k++; } t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_delete_page_log_n_extra(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 0, v = 1; while (k < 12) { t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); k++; } t( sp_destroy(db) == 0 ); t( exists(dbrep, 1, "log") == 1 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { t( sp_delete(db, &k, sizeof(k)) == 0); k++; } k = 13; v = k; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); t( exists(dbrep, 2, "log.incomplete") == 1 ); t( sp_ctl(db, SPMERGEFORCE) == 0); t( exists(dbrep, 1, "db") == 0 ); t( exists(dbrep, 2, "db") == 1 ); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { size_t vsize = 0; void *vp = NULL; t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 0 ); k++; } k = 13; size_t vsize = 0; void *vp = NULL; t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 1 ); t( vsize == sizeof(v) ); t( *(uint32_t*)vp == 13 ); free(vp); t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_delete_page_log_n_fetch_gte(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 0, v = 1; while (k < 12) { v = k; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); k++; } t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { if (k > 0 && (k % 2) == 0) t( sp_delete(db, &k, sizeof(k)) == 0); k++; } t( sp_ctl(db, SPMERGEFORCE) == 0); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); void *cur = sp_cursor(db, SPGTE, NULL, 0); t( cur != NULL ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 0 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 0 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 1 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 1 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 3 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 3 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 5 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 5 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 7 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 7 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 9 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 9 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 11 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 11 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 0 ); t( sp_destroy(cur) == 0 ); t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_delete_page_log_n_fetch_lte(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 0, v = 1; while (k < 12) { v = k; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); k++; } t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { if (k > 0 && (k % 2) == 0) t( sp_delete(db, &k, sizeof(k)) == 0); k++; } t( sp_ctl(db, SPMERGEFORCE) == 0); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); void *cur = sp_cursor(db, SPLTE, NULL, 0); t( cur != NULL ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 11 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 11 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 9 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 9 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 7 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 7 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 5 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 5 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 3 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 3 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 1 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 1 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 0 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 0 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 0 ); t( sp_destroy(cur) == 0 ); t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_delete_page_log_n_fetch_kgte(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 0, v = 1; while (k < 12) { v = k; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); k++; } t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { if (k > 0 && (k % 2) == 0) t( sp_delete(db, &k, sizeof(k)) == 0); k++; } t( sp_ctl(db, SPMERGEFORCE) == 0); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 6; void *cur = sp_cursor(db, SPGTE, &k, sizeof(k)); t( cur != NULL ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 7 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 7 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 9 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 9 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 11 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 11 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 0 ); t( sp_destroy(cur) == 0 ); t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } static void merge_delete_page_log_n_fetch_klte(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); t( sp_ctl(env, SPGC, 0) == 0 ); t( sp_ctl(env, SPMERGE, 0) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 0, v = 1; while (k < 12) { v = k; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); k++; } t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 0; while (k < 12) { if (k > 0 && (k % 2) == 0) t( sp_delete(db, &k, sizeof(k)) == 0); k++; } t( sp_ctl(db, SPMERGEFORCE) == 0); t( sp_destroy(db) == 0 ); db = sp_open(env); t( db != NULL ); k = 6; void *cur = sp_cursor(db, SPLTE, &k, sizeof(k)); t( cur != NULL ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 5 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 5 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 3 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 3 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 1 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 1 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 1 ); t( *(uint32_t*)sp_key(cur) == 0 ); t( sp_keysize(cur) == sizeof(k) ); t( *(uint32_t*)sp_value(cur) == 0 ); t( sp_valuesize(cur) == sizeof(v) ); t( sp_fetch(cur) == 0 ); t( sp_destroy(cur) == 0 ); t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); } int main(int argc, char *argv[]) { rmrf(dbrep); test(merge_liveonly); test(merge_phase0); test(merge_phase1); test(merge_phase1gc); test(merge_phase1n); test(merge_phase1ngc); test(merge_delete); test(merge_deletegc); test(merge_delete_log_n); test(merge_delete_page_n); test(merge_delete_page_log_n); test(merge_delete_page_log_n_even); test(merge_delete_page_log_n_extra); test(merge_delete_page_log_n_fetch_gte); test(merge_delete_page_log_n_fetch_lte); test(merge_delete_page_log_n_fetch_kgte); test(merge_delete_page_log_n_fetch_klte); return 0; }