#include #include #include #include #include #include "amap.h" #include "simap.h" #include "mapmap.hpp" /** * Creates keys or returns the ith key. Used for performance tests. * * @param i When "create" is false, we return the ith key (does not check OOB) * @param create When true, we initialize the keystore with keys generated from 0..i indices. * @returns The ith key when create==false, otherwise undefined. */ inline const char *keystore(int i, bool create = false) noexcept { static thread_local std::vector keys; if(!create) { return keys[i].c_str(); } else { keys.resize(0); keys.reserve(0); std::string key = "k"; for(int j = 0; j < i; ++j) { keys.push_back(key + std::to_string(j)); } return NULL; } } /** * Creates keys or returns the ith key. Used for performance tests. * * @param i When "create" is false, we return the ith data (does not check OOB) * @param create When true, we initialize the datastore with datas generated from 0..i indices. * @returns The ith data when create==false, otherwise undefined. */ inline int *datastore(int i, bool create = false) noexcept { static thread_local std::vector keys; if(!create) { return &(keys[i]); } else { keys.resize(0); keys.reserve(0); for(int j = 0; j < i; ++j) { keys.push_back(j); } return NULL; } } void test_perf(amap mapdo, void *map, int max_key, const char *what) { auto begin = std::chrono::high_resolution_clock::now(); for(int i = 0; i < max_key; ++i) { const char *key = keystore(i); int *data = datastore(i); mapdo(map, AMAP_SET, key, data); } auto end = std::chrono::high_resolution_clock::now(); auto elapsed = std::chrono::duration_cast(end - begin); printf("Insertion time for %d elements (%s): %.3f ms.\n", max_key, what, elapsed.count() * 1e-6); } void test_basics(amap mapdo, void *map) { /* Most basics */ assert(NULL == mapdo(map, AMAP_GET, "asdf", NULL)); int i = 42; int *iptr; const char *chptr; assert(NULL != mapdo(map, AMAP_SET, "meaning", &i)); assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "meaning", NULL))); assert(*iptr == 42); assert(iptr == &i); /* Delete / tombstone */ assert(NULL != mapdo(map, AMAP_SET, "meaning", NULL)); assert(NULL == (int *)mapdo(map, AMAP_GET, "meaning", NULL)); /* Check re-adding */ assert(NULL != mapdo(map, AMAP_SET, "meaning", &i)); assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "meaning", NULL))); assert(*iptr == 42); assert(iptr == &i); /* Test Erase */ assert(NULL != mapdo(map, AMAP_ERASE, NULL, NULL)); /* Check re-adding 3 new things */ assert(NULL != mapdo(map, AMAP_SET, "meaningless1", &i)); assert(NULL != mapdo(map, AMAP_SET, "meaning2", &i)); const char *helloworld = "Hello world!"; assert(NULL != mapdo(map, AMAP_SET, "hello", (char *)helloworld)); /* ugly cast... */ assert(NULL != (chptr = (const char *)mapdo(map, AMAP_GET, "hello", NULL))); assert(strlen(chptr) == strlen(helloworld)); assert(strcmp(chptr, helloworld) == 0); assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "meaning2", NULL))); assert(*iptr == 42); assert(iptr == &i); assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "meaningless1", NULL))); assert(*iptr == 42); assert(iptr == &i); } int main() { /* Basic tests */ simap_instance si = simap_create(); test_basics(simap, &si); mapmap_instance mi = mapmap_create(); test_basics(mapmap, &mi); /* Performance tests */ int i = 1000; keystore(i, true); datastore(i, true); test_perf(mapmap, &mi, i, "std::map"); test_perf(simap, &si, i, "simap"); return 0; }