⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 PB 熟悉的哥们希望大家可以互相学习一下
💻 C
字号:
/***************************************************************
 *                                                             *
 * Copyright (c) 2001-2007 McObject LLC. All Right Reserved.   *
 *                                                             *
 ***************************************************************/

/* 
 * This sample demonstrate the use of eXtremeDB for the Routing Table Management software.
 * The program measures the performance for routing table inserts and lookups. The program
 * randomly generates IP addresses, each masked with three masks - 255.255.0.0, 255.255.255.0
 * or 255.255.255.255. We then insert these routes into the routing table, creating a
 * hash-based index based on the {mask/ip address} pair. The database engine filters out
 * duplicate pairs of {mask/ip address} as the new routes are installed into the routing table.
 * After the table is populated, the program searches for a route for a random packet.
 * The algorithm is a combination of a linear search and a tree search, masking the address with
 * each of the three possible masks and then using the index to locate the route. Therefore each
 * address is searched up to three times to find the best match. If more than one route exists,
 * the one with the longest matching prefix is chosen.
 *
 * A somewhat detailed discussion of the routing table implementaion using eXtremeDB
 * could be found in the whitepaper "The Role of In-Memory Database Systems in Routing
 * Table Management in IP Routers" - http://mcobject.com/whitepapers.htm
 */

#include <platform.h>
#include <stdio.h>
#include <stdlib.h>

#include "rtdb.h"

static const char* dbname = "Route1";
static const int SEGSZ = 1024 * 1024 * 16UL;
#ifndef MCO_PLATFORM_X64
    static const int PAGESIZE = 96;
#else 
    static const int PAGESIZE = 192;
#endif 


const int MAP_ADDRESS = 0x20000000;

#define NROUTES    200000
#define NSEARCHES  500000

static void _SH_(void)
{

    char text[] = 
    {
        "\nThis sample demonstrate the use of eXtremeDB for the Routing Table\n"
            "Management software.The program measures the performance for routing\n"
            "randomly generates IP addresses, each masked with three masks - 255.255.0.0,\n"
            "255.255.255.0 or 255.255.255.255. We then insert these routes into the\n"
            "routing table.After the table is populated, the program searches for a route\n"
            "for a random packet.The algorithm is a combination of a linear search and\n"
            "a tree search, masking the address with each of the three possible masks and\n"
            "then using the index to locate the route.\n"
    };

    char text1[] = 
    {
        "Copyright (c) 2001-2007 McObject LLC. All Right Reserved.\n\n"
    };

    printf("%s\neXtremeDB runtime version %d.%d, build %d\n%s\n\nPress Enter to start", text, MCO_COMP_VER_MAJOR,
           MCO_COMP_VER_MINOR, MCO_COMP_BUILD_NUM, text1);

    getchar();
}


/* Produces database memory report
 */
void showMem(mco_db_h db)
{
    mco_puint freepg, totalpg;

    mco_db_free_pages(db, &freepg);
    mco_db_total_pages(db, &totalpg);

    printf("\n\tMemory Report:\n\ttotal pages=%d (%dK)\n\tfree pages=%d (%dK)\n\tused %dK\n", totalpg, totalpg*
           PAGESIZE / 1024, freepg, freepg* PAGESIZE / 1024, (totalpg - freepg)* PAGESIZE / 1024);
}


/* fatal error handler */
static void errhandler(int n)
{
    printf("\neXtremeDB fatal error: %d", n);
    getchar();
    exit( - 1);
}


static uint1 calcNbits(uint4 mask)
{
    static int n8[16] = 
    {
        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
    };
    int rc = 0, i;
    for (i = 0; i < 8; i++)
    {
        int halfbt = (mask >> (i << 2)) &15;
        rc += n8[halfbt];
    }
    return (uint1)rc;
}


static MCO_RET addRoute(mco_db_h db, uint4 dest, uint4 mask, uint4 gatew, uint4 interf, uint2 weight)
{
    MCO_RET rc;
    mco_trans_h t;
    Mask hmask;
    Route rt;
    uint1 nbit = calcNbits(mask);
    // mco_cursor_t csr;

    rc = mco_trans_start(db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t);
    if (rc)
    {
        return rc;
    }

    // add mask if need:
    rc = Mask_all_find(t, nbit, mask, &hmask);
    if (rc == MCO_S_NOTFOUND)
    {
        rc = Mask_new(t, &hmask);
        if (rc)
        {
            goto End;
        }
        Mask_mask_put(&hmask, mask);
        Mask_nbits_put(&hmask, nbit);
    }
    else
    {
        if (rc)
        {
            goto End;
        }
    }

    // add route:
    rc = Route_new(t, &rt);
    if (rc)
    {
        goto End;
    }

    Route_dest_put(&rt, dest);
    Route_mask_put(&rt, mask);
    Route_gateway_put(&rt, gatew);
    Route_interf_put(&rt, interf);
    Route_metric_put(&rt, weight);

    End: rc = mco_trans_commit(t);
    return rc;
}


static uint4 genIP(void)
{
    uint4 rc = 0x2A3B0000;
    int rn = rand() | (rand() << 16);

    rc |= rn &0xFFFFFF;
    if (rn &0x01000000)
    {
        rc |= 0x0E000000; // ^= (rn & 0x0F000000);
    }
    return rc;
}


static uint4 genMask(uint4 ip)
{
    int rn = rand() &15;
    if (rn < 12)
    {
        return 0xFFFFFFFF;
    }
    if (rn < 15)
    {
        return 0xFFFFFF00;
    }
    return 0xFFFF0000;
}


static const char* prtip(uint4 n)
{
    static char rc[100];
    sprintf(rc, "%03d.%03d.%03d.%03d  ", (n >> 24) &255, (n >> 16) &255, (n >> 8) &255, (n) &255);
    return rc;
}


/* This is used to dump the content of the routing table into the file
 * In oredr to use this, change the schema so, that the tree index is
 * declared, and remove the #define DUMP_TABLE on the top of this file
 */
//#define DUMP_TABLE
static void dumpRoutingTable(mco_db_h db, const char* fnm)
{
    #ifdef DUMP_TABLE
        FILE* f = fopen(fnm, "w");

        mco_cursor_t csr;
        Route rt;
        uint4 mask, dest, gateway, interf;
        mco_trans_h t;
        MCO_RET rc;

        if (!f)
        {
            return ;
        }

        mco_trans_start(db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t);

        Route_byMaskDest_index_cursor(t, &csr);

        for (rc = mco_cursor_first(t, &csr); rc == MCO_S_OK; rc = mco_cursor_next(t, &csr))
        {
            Route_from_cursor(t, &csr, &rt);
            Route_dest_get(&rt, &dest);
            Route_mask_get(&rt, &mask);
            Route_interf_get(&rt, &interf);
            Route_gateway_get(&rt, &gateway);

            fprintf(f, "%s", prtip(dest));
            fprintf(f, "%s", prtip(mask));
            fprintf(f, "%s", prtip(gateway));
            fprintf(f, "%s", prtip(interf));
            fprintf(f, "\n");

        }

        mco_trans_commit(t);
        fclose(f);
    #endif 
}


/* 
 * searchRoute()
 */
static int searchRoute(mco_db_h db, uint4 ip, uint4* res_gatew, uint4* res_interf)
{
    MCO_RET rc;
    mco_cursor_t csr;
    Mask hmask;
    uint4 mask;
    mco_trans_h t;

    int ok = 0;

    rc = mco_trans_start(db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &t);
    if (rc)
    {
        return rc;
    }

    // scan all possible masks
    rc = Mask_all_index_cursor(t, &csr);
    if (rc)
    {
        goto End;
    }

    for (rc = mco_cursor_last(t, &csr); rc == MCO_S_OK; rc = mco_cursor_prev(t, &csr))
    {
        Route rt;

        Mask_from_cursor(t, &csr, &hmask);
        Mask_mask_get(&hmask, &mask);
        rc = Route_byMaskDest_find(t, mask, mask &ip, &rt);
        if (rc == MCO_S_OK)
        {
            ok = 1;
            break;
        }
    }

    End: rc = mco_trans_commit(t);
    return ok;

}


static void dodo(mco_db_h db)
{
    int j;
    MCO_RET rc;
    uint4 gway = genIP();
    uint4 interf = genIP();
    int nok = 0;
    int nskipped = 0;
    uint4 ip;
    uint4 mask;

    time_t t1, t2, t3, t4;

    printf("\nPopulating Routing Table with %d randomly generated routes\n", NROUTES);
    Sleep(50);
    time(&t1);
    for (j = 0; j < NROUTES; j++)
    {

        ip = genIP();
        mask = genMask(ip);
        ip = ip &mask;

        rc = addRoute(db, ip, mask, gway, interf, 1);

        if (rc)
        {
            if (rc == MCO_S_DUPLICATE)
            {
                nskipped++;
            }
            else
            {
                printf("\nRoute add error: %d", rc);
                break;
            }
        }
        if (j % 5000 == 0)
        {
            printf(".");
        }
    }
    time(&t2);

    printf("\nAdded %d routes, %d duplicate routes rejected -- %d sec\n\n", j - nskipped, nskipped, t2 - t1);
    Sleep(50);
    showMem(db);

    dumpRoutingTable(db, "rt_.txt");

    printf("\nLooking for a random IP %d times\n", NSEARCHES);
    Sleep(50);

    time(&t3);
    for (j = 0; j < NSEARCHES; j++)
    {
        uint4 ip = genIP();
        uint4 res_gatew, res_interf;
        int ok = searchRoute(db, ip, &res_gatew, &res_interf);
        if (ok)
        {
            nok++;
        }
        if (j % 5000 == 0)
        {
            printf(".");
        }
    }
    time(&t4);

    printf("\nSearched %d destinations -- %d sec -- %d succeeded\n\n", j, t4 - t3, nok);

}


int main(void)
{
    MCO_RET rc;
    mco_db_h db = 0;
    char* start_mem;
    mco_runtime_info_t info;

    _SH_();
    mco_get_runtime_info(&info);
    if (info.mco_shm_supported)
    {
        start_mem = (char*)MAP_ADDRESS;
    }
    else
    {
        start_mem = (char*)malloc(SEGSZ);
        if (!start_mem)
        {
            printf("Couldn't allocated memory\n");
            exit(1);
        }
    };

    /* set fatal error handler */
    mco_error_set_handler(&errhandler);

    rc = mco_runtime_start();

    /* Create a database, using first memory segment */
    rc = mco_db_open(dbname, rtdb_get_dictionary(), start_mem, SEGSZ, (uint2)PAGESIZE);

    if (rc)
    {
        printf("\nerror creating database");
        if (!info.mco_shm_supported)
        {
            free(start_mem);
        }
        exit(1);
    }

    /* connect to the database, obtain a database handle */
    mco_db_connect(dbname, &db);
    showMem(db);

    dodo(db);

    /* disconnect from the database, db is no longer valid */
    mco_db_disconnect(db);

    /* destroys the memory manager */
    mco_db_close(dbname);

    mco_runtime_stop();

    if (!info.mco_shm_supported)
    {
        free(start_mem);
    }

    printf("press Enter to finish \n");
    getchar();
    PROG_EXIT(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -