Using the Flash Simulator

Tying up the Simulator with the database runtime example:

    static void create_database(const char *db_name, mco_device_t *devs)
    {
        mco_db_params_t    db_params;
        mco_flashsim_params_t fsp = {0};

        /* --- Configure flash simulator parameters --- */
        fsp.page_size       = P_RAMFLASH_PAGE_SIZE;        /* Page size in bytes (must be power of two) */
        fsp.pages_per_block = P_RAMFLASH_PAGES_PER_BLOCK;  /* Number of pages per erase block */
        fsp.n_blocks        = P_RAMFLASH_NUM_BLOCKS;       /* Total number of erase blocks */
        fsp.image_filename  = g_flash_image_file_name;     /* Optional file to persist flash content across runs */

        /* --- Device 0: main database memory (RAM) --- */
        devs[0].assignment = MCO_MEMORY_ASSIGN_DATABASE;
        devs[0].size       = P_DB_SIZE;
        devs[0].type       = MCO_MEMORY_CONV;
        devs[0].dev.conv.ptr = (char*)malloc(devs[0].size);
        devs[0].dev.conv.flags = 0;

        /* --- Device 1: database cache (RAM) --- */
        devs[1].assignment = MCO_MEMORY_ASSIGN_CACHE;
        devs[1].size       = P_DB_CACHE_SZ;
        devs[1].type       = MCO_MEMORY_CONV;
        devs[1].dev.conv.ptr = (char*)malloc(devs[1].size);
        devs[1].dev.conv.flags = 0;

        /* --- Device 2: persistent storage device (bound to flash simulator via media_context) --- */
        devs[2].assignment = MCO_MEMORY_ASSIGN_PERSISTENT;
        devs[2].type       = MCO_MEMORY_FILE;              /* FILE type indicates external media context will be used */
        devs[2].dev.file.flags = MCO_FILE_OPEN_WITH_MEDIA_CTX; /* Use media_context instead of a filename */
        devs[2].dev.file.name[0] = '\0';                   /* Filename is ignored — media context provides I/O backend */

        /* --- Device 3: memory for flash simulator internal state --- */
        devs[3].assignment = MCO_MEMORY_ASSIGN_PERSISTENT;
        devs[3].size       = mco_flashsim_memory_size(&fsp); /* Calculate required memory size based on geometry */
        devs[3].type       = MCO_MEMORY_CONV;
        devs[3].dev.conv.ptr = (char*)malloc(devs[3].size);
        devs[3].dev.conv.flags = 0;

        /* --- Initialize the flash simulator instance --- */
        CHECK(mco_flashsim_open(&devs[3], &fsp, &g_flash_handle)); /* Open simulator using allocated memory */

        /* --- Bind simulator to the persistent device via media context --- */
        /* mco_flashsim_media_context() returns a pointer to the simulator's internal mco_device_t,
        which eXtremeDB uses as the I/O backend for flash operations. */
        CHECK(mco_flashsim_media_context(g_flash_handle,
                                        &devs[2].dev.file.media_context,
                                        &devs[2].dev.file.media_context_size));

        /* --- Configure database parameters --- */
        mco_db_params_init(&db_params);
        db_params.mode_mask                 = P_DB_MODE_MASK;
        db_params.mem_page_size             = P_DB_MEM_PAGE_SZ;
        db_params.disk_page_size            = P_DB_DISK_PAGE_SZ;
        db_params.disk_max_database_size    = P_DB_DISK_MAX_SIZE;
        db_params.db_max_connections        = 16;
        db_params.meta_cache_lines          = P_DB_META_CACHE_LINES;
        db_params.meta_cache_ways           = P_DB_META_CACHE_WAYS;
        db_params.flash_gc_ratio            = P_DB_FLASH_GC_RATIO;

        /* --- Open database with RAM, cache, and simulated flash devices --- */
        CHECK(mco_db_open_dev(db_name, perf_get_dictionary(), devs, 3, &db_params));
    }

    ...

    int perf(const char *image_name)
    {
        mco_device_t devices[4];
        mco_db_h db;

        g_flash_image_file_name = image_name;

        mco_error_set_handler(&errhandler);
        CHECK(mco_runtime_start());

        create_database("perf_db", devices);               /* Create and open DB with flash simulator */
        CHECK(mco_db_connect("perf_db", &db));

        do_perf(db, 1000);                                 /* Run test workload */

        /* --- Print flash simulator statistics and block health map --- */
        /* Shows operation counts, data volume, timing, and visual block status:
        '.' = healthy, '!' = error, 'X' = bad block */
        mco_flashsim_print_stat(g_flash_handle, 128);      /* 128 blocks per line in the map */

        /* --- Save simulator state to image file (if filename was provided) --- */
        /* Enables exact state restoration on next run for debugging or regression testing */
        if (g_flash_image_file_name) {
            CHECK(mco_flashsim_save_image(g_flash_handle, NULL)); /* Uses filename from fsp.image_filename */
        }

        CHECK(mco_db_disconnect(db));
        destroy_database("perf_db", devices);
        mco_runtime_stop();
        return 0;
    }