📄 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. * 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_X64static const int PAGESIZE = 96;#elsestatic const int PAGESIZE = 192;#endifconst int MAP_ADDRESS = 0x20000000;#define NROUTES 200000#define NSEARCHES 500000static 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_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 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 + -