📄 main.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 using * patricia index prefix match function. * * 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 = "Route2";static const int SEGSZ = 1024 * 1024 * 32UL;#ifndef MCO_PLATFORM_X64static const int PAGESIZE = 96;#elsestatic const int PAGESIZE = 192;#endifconst int MAP_ADDRESS = 0x20000000;#define NROUTES 200000#define NSEARCHES 500000static const char * prtip(uint4 n);const uint4 _mask[4]={0xff000000,0xffff0000,0xffffff00,0xffffffff};#define get_mask(nbits) _mask[(nbits/8)-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 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 using patricia index prefix match function.\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 MCO_RET addRoute(mco_db_h db,uint4 dest, uint4 mask, uint4 gatew, uint4 interf, uint2 weight) { MCO_RET rc; mco_trans_h t; Route rt; uint1 nbit = ((calcNbits(mask)+7)/8)*8; rc = mco_trans_start(db,MCO_READ_WRITE,MCO_TRANS_FOREGROUND,&t); if(rc) return rc; // add route: rc = Route_new(t, &rt); if(rc) goto End; dest=dest>>(32-nbit); Route_dest_alloc(&rt,nbit); Route_dest_put_range(&rt,0,nbit,(uint1*)&dest); 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_TABLEstatic void dumpRoutingTable(mco_db_h db, const char *fnm) {#ifdef DUMP_TABLE FILE * f = fopen(fnm, "w"); mco_cursor_t csr; Route rt; uint4 dest, gateway, interf; uint2 blen; mco_trans_h t; MCO_RET rc; if(! f) return; mco_trans_start(db,MCO_READ_WRITE,MCO_TRANS_FOREGROUND,&t); Route_byDest_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); dest = 0; Route_dest_size(&rt,&blen); Route_dest_get_range(&rt,0,blen,&dest); dest=dest<<(32-blen); Route_interf_get(&rt, &interf); Route_gateway_get(&rt, &gateway); fprintf(f, "%s", prtip( dest ) ); fprintf(f, "%s", prtip( get_mask(blen) ) ); 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; mco_trans_h t; Route rt; uint4 dest; int ok = 0; uint2 blen; rc = mco_trans_start(db,MCO_READ_ONLY,MCO_TRANS_FOREGROUND,&t); if(rc) return rc; rc = Route_byDest_index_cursor(t,&csr); if(rc) return rc; rc = Route_byDest_prefix_match(t,&csr,(uint1*)&ip,32); if(rc == MCO_S_OK) { rc = Route_from_cursor(t,&csr,&rt); if(rc) return rc; dest = 0; rc = Route_dest_size(&rt,&blen); if(rc) return rc; rc = Route_dest_get_range(&rt,0,blen,(uint1*)&dest); if(rc) return rc; dest=dest<<(32-blen); if (dest==(ip&get_mask(blen))) ok = 1; } 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; uint1 cycle=0; time_t t1, t2, t3, t4; uint4 wasfound=0; printf ("\nPopulating Routing Table with %d randomly generated routes\n", NROUTES); Sleep(50); time(&t1); for(j=0; j<NROUTES; j++) { cycle=0; 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 + -