c-core/20_core/core20Example_main.c
/*
 * Raima Database Manager
 *
 * Copyright (c) 2019 Raima Inc.,  All rights reserved.
 *
 * Use of this software, whether in source code format, or in executable,
 * binary object code form, is governed by the Raima LICENSE which
 * is fully described in the LICENSE.TXT file, included within this
 * distribution of files.
 */
 
#include <stdio.h>
#include "example_fcns.h"
#include "rdm.h"
#include "rdmstartupapi.h"
 
/* Generated \c struct and \c typedef definitions to be used with the RDM APIs
 */
#include "core20_structs.h"
 
/* Generated catalog definition to be used with the RDM rdm_dbSetCatalog() API
 */
#include "core20_cat.h"
 
const char *const description =
    "Performance Test (inmemory): reading in rowid order";
const RDM_CMDLINE_OPT opts[] = {{NULL, NULL, NULL, NULL}};
 
RDM_RETCODE add_records (
    RDM_DB hDB) 
{
    RDM_RETCODE rc;
    SIMPLE simple_rec = {0};
    perfTimer_t timer;
    int ii;
 
    timeMeasureBegin (&timer);
 
    rc = rdm_dbStartUpdate (hDB, RDM_LOCK_ALL, 0, NULL, 0, NULL);
    print_error (rc);
 
    if (rc == sOKAY)
    {
        /* Loop to add 50,000 new simple record */
        for (ii = 0; ii < 50000; ii++)
        {
            /* Set values for the new record */
            simple_rec.int_col = 1;
 
            /* Add the record to the database */
            rc = rdm_dbInsertRow (
                hDB, TABLE_SIMPLE, &simple_rec, sizeof (simple_rec), NULL);
            print_error (rc);
        }
        rdm_dbEnd (hDB);
    }
 
    timeMeasureEnd (&timer);
    printf (
        "Add 50,000 records:\t\t\t\t%u milliseconds\n",
        timeMeasureDiff (&timer));
    return rc;
}
 
RDM_RETCODE read_records (
    RDM_DB hDB) 
{
    RDM_RETCODE rc = sOKAY;
    SIMPLE simple_rec;
    RDM_CURSOR cursor;
    perfTimer_t timer;
    unsigned int total = 0;
 
    timeMeasureBegin (&timer);
 
    rc = rdm_dbStartRead (hDB, RDM_LOCK_ALL, 0, NULL);
    print_error (rc);
 
    if (rc == sOKAY)
    {
        /* allocate a cursor resource */
        rc = rdm_dbAllocCursor (hDB, &cursor);
        print_error (rc);
 
        if (rc == sOKAY)
        {
            /* Fill a cursor with all the rows in a table */
            rc = rdm_dbGetRows (hDB, TABLE_SIMPLE, &cursor);
            print_error (rc);
 
            if (rc == sOKAY)
            {
                /* Loop through each simple record in table order */
                for (rc = rdm_cursorMoveToFirst (cursor); rc == sOKAY;
                     rc = rdm_cursorMoveToNext (cursor))
                {
                    /* Read the record */
                    rc = rdm_cursorReadRow (
                        cursor, &simple_rec, sizeof (simple_rec), NULL);
                    print_error (rc);
 
                    if (rc == sOKAY)
                    {
                        /* Add the value read to the running sum */
                        total += simple_rec.int_col;
                    }
                }
            }
            /* Free the cursor */
            rdm_cursorFree (cursor);
        }
        rdm_dbEnd (hDB);
    }
 
    timeMeasureEnd (&timer);
 
    /* We expect rc to be sENDOFCURSOR when we break out of the loop */
    if (rc == sENDOFCURSOR)
    {
        printf (
            "Scanning, reading, summing 50,000 records:\t%u milliseconds\n",
            timeMeasureDiff (&timer));
        printf ("\tSum = %u\n", total);
        rc = sOKAY;
    }
    return rc;
}
 
RDM_RETCODE update_records (
    RDM_DB hDB) 
{
    RDM_RETCODE rc;
    SIMPLE simple_rec;
    RDM_CURSOR cursor;
    perfTimer_t timer;
 
    timeMeasureBegin (&timer);
 
    rc = rdm_dbStartUpdate (hDB, RDM_LOCK_ALL, 0, NULL, 0, NULL);
    print_error (rc);
 
    if (rc == sOKAY)
    {
        /* allocate a cursor resource */
        rc = rdm_dbAllocCursor (hDB, &cursor);
        print_error (rc);
 
        if (rc == sOKAY)
        {
            /* Fill a cursor with all the rows in a table */
            rc = rdm_dbGetRows (hDB, TABLE_SIMPLE, &cursor);
            print_error (rc);
 
            if (rc == sOKAY)
            {
                /* Loop through each simple record in table order */
                for (rc = rdm_cursorMoveToFirst (cursor); rc == sOKAY;
                     rc = rdm_cursorMoveToNext (cursor))
                {
                    /* Read the record */
                    rc = rdm_cursorReadRow (
                        cursor, &simple_rec, sizeof (simple_rec), NULL);
                    print_error (rc);
 
                    if (rc == sOKAY)
                    {
                        /* increment the inc_col field */
                        simple_rec.int_col++;
 
                        /* Update the simple record with the new int_col value
                         */
                        rc = rdm_cursorUpdateRow (
                            cursor, &simple_rec, sizeof (simple_rec));
                        print_error (rc);
                    }
                }
            }
            /* Free the cursor */
            rdm_cursorFree (cursor);
        }
        rdm_dbEnd (hDB);
    }
 
    timeMeasureEnd (&timer);
 
    /* We expect rc to be sENDOFCURSOR when we break out of the loop */
    if (rc == sENDOFCURSOR)
    {
        printf (
            "Updating 50,000 records:\t\t\t%u milliseconds\n",
            timeMeasureDiff (&timer));
        rc = sOKAY;
    }
    return rc;
}
 
RDM_RETCODE delete_records (
    RDM_DB hDB) 
{
    RDM_RETCODE rc;
    RDM_CURSOR cursor = NULL;
    perfTimer_t timer;
 
    timeMeasureBegin (&timer);
 
    rc = rdm_dbStartUpdate (hDB, RDM_LOCK_ALL, 0, NULL, 0, NULL);
    print_error (rc);
 
    if (rc == sOKAY)
    {
        /* Fill a cursor with all the rows in a table */
        rc = rdm_dbGetRows (hDB, TABLE_SIMPLE, &cursor);
        print_error (rc);
 
        if (rc == sOKAY)
        {
            /* Loop through each simple record in table order */
            for (rc = rdm_cursorMoveToLast (cursor); rc == sOKAY;
                 rc = rdm_cursorMoveToPrevious (cursor))
            {
                /* Read the record */
                rc = rdm_cursorDeleteRow (cursor);
                print_error (rc);
            }
            /* Free the cursor */
            rdm_cursorFree (cursor);
        }
        rdm_dbEnd (hDB);
    }
 
    timeMeasureEnd (&timer);
 
    /* We expect rc to be sENDOFCURSOR when we break out of the loop */
    if (rc == sENDOFCURSOR)
    {
        printf (
            "Deleting 50,000 records:\t\t\t%u milliseconds\n",
            timeMeasureDiff (&timer));
        rc = sOKAY;
    }
    return rc;
}
 
int main_core20 (int argc, const char *const *argv)
{
    RDM_TFS hTFS;
    RDM_DB hDB;
    RDM_RETCODE rc;
    perfTimer_t timer;
 
    rc = rdm_cmdlineInit (&cmd, argc, argv, description, opts);
    if (rc != sCMD_USAGE)
        print_error (rc);
 
    /* Initialize the handles and open the database */
 
    timeMeasureBegin (&timer);
    rc = exampleOpenEmptyDatabaseInMemory (&hTFS, &hDB, "core20", core20_cat);
    timeMeasureEnd (&timer);
    if (rc == sOKAY)
    {
        /* Display information */
        printf (
            "Preparing a new database:\t\t\t%u milliseconds\n",
            timeMeasureDiff (&timer));
        printf ("\tOne, simple record type.\n");
        printf ("\tIn-memory\n");
    }
 
    if (rc == sOKAY)
    {
        /* Add 50,000 records to the database */
        rc = add_records (hDB);
        if (rc == sOKAY)
        {
            /* Read all of the records in the database */
            rc = read_records (hDB);
        }
        if (rc == sOKAY)
        {
            /* Update all of the records in the database */
            rc = update_records (hDB);
        }
        if (rc == sOKAY)
        {
            /* Read all of the records in the database */
            rc = read_records (hDB);
        }
        if (rc == sOKAY)
        {
            /* Remove all of the records in the database */
            rc = delete_records (hDB);
        }
        timeMeasureBegin (&timer);
        exampleCleanup (hTFS, hDB);
        timeMeasureEnd (&timer);
        printf (
            "Cleanup:\t\t\t\t\t%u milliseconds\n", timeMeasureDiff (&timer));
    }
    return (int) rc;
}
 
RDM_RETCODE rdm_cursorMoveToFirst(RDM_CURSOR cursor)
Position a cursor to the first row in the collection.
RDM_RETCODE rdm_cursorMoveToNext(RDM_CURSOR cursor)
Position a cursor to the next row in the collection.
Header for the native RDM Runtime API.
RDM_RETCODE rdm_dbEnd(RDM_DB db)
End a transactional operation.
@ sCMD_USAGE
Definition: rdmretcodetypes.h:71
struct RDM_CURSOR_S * RDM_CURSOR
Definition: rdmtypes.h:304
RDM_RETCODE rdm_dbStartRead(RDM_DB db, const RDM_TABLE_ID *tableIds, uint32_t numTableIds, RDM_TRANS *pTrans)
Get read locks.
RDM_RETCODE rdm_cursorReadRow(RDM_CURSOR cursor, void *colValues, size_t bytesIn, size_t *bytesOut)
Read all columns from a row.
The buffer used by the command line parser to hold state information.
Definition: rdmcmdlinetypes.h:85
RDM_RETCODE rdm_cursorDeleteRow(RDM_CURSOR cursor)
Delete a row from a table.
@ sOKAY
Definition: rdmretcodetypes.h:95
Generic usage function option record.
Definition: rdmcmdlinetypes.h:32
RDM_RETCODE rdm_cursorMoveToPrevious(RDM_CURSOR cursor)
Position a cursor to the previous row in the collection.
RDM_RETCODE rdm_cursorFree(RDM_CURSOR cursor)
Free an RDM_CURSOR.
#define RDM_STARTUP_EXAMPLE(name)
Definition: rdmstartuptypes.h:73
RDM_RETCODE rdm_dbGetRows(RDM_DB db, RDM_TABLE_ID tableId, RDM_CURSOR *pCursor)
Associate an RDM_CURSOR with rows based on a table id.
RDM_RETCODE rdm_dbAllocCursor(RDM_DB db, RDM_CURSOR *pCursor)
Allocate a cursor.
RDM_RETCODE rdm_dbInsertRow(RDM_DB db, RDM_TABLE_ID tableId, const void *colValues, size_t bytesIn, RDM_CURSOR *pCursor)
Insert a new row into a table at the specified rowId.
RDM_RETCODE rdm_cursorMoveToLast(RDM_CURSOR cursor)
Position a cursor to the last row in the collection.
struct RDM_TFS_S * RDM_TFS
RDM TFS Handle.
Definition: rdmtfstypes.h:21
RDM_RETCODE rdm_cmdlineInit(RDM_CMDLINE *cmd, int32_t argc, const char *const argv[], const char *description, const RDM_CMDLINE_OPT *opts)
Initialize an RDM_CMDLINE buffer and validate the command line.
struct RDM_DB_S * RDM_DB
Definition: rdmtypes.h:303
RDM_RETCODE rdm_cursorUpdateRow(RDM_CURSOR cursor, const void *colValues, size_t bytesIn)
Update all columns in a row.
#define RDM_LOCK_ALL
Definition: rdmtypes.h:170
RDM_RETCODE rdm_dbStartUpdate(RDM_DB db, const RDM_TABLE_ID *writeTableIds, uint32_t numWriteTableIds, const RDM_TABLE_ID *readTableIds, uint32_t numReadTableIds, RDM_TRANS *pTrans)
Get write locks.
@ sENDOFCURSOR
Definition: rdmretcodetypes.h:58
Internal RDM Startup API used by startup macros.
RDM_RETCODE
RDM status and error return codes.
Definition: rdmretcodetypes.h:43