X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fstrset%2Ftools%2Fcbspeed.c;fp=ccan%2Fstrset%2Ftools%2Fcbspeed.c;h=a1766490341d2acade525dd419ffbd5184e10f3e;hp=0000000000000000000000000000000000000000;hb=5c559e7df1d31b4c0ddf26451fac972dc8a0c2c9;hpb=ab83de953730f5e5e571dbf69ffb3cc685a102dc diff --git a/ccan/strset/tools/cbspeed.c b/ccan/strset/tools/cbspeed.c new file mode 100644 index 00000000..a1766490 --- /dev/null +++ b/ccan/strset/tools/cbspeed.c @@ -0,0 +1,590 @@ +/* Simple speed tests using original critbit code (modified not to allocate). + * + * Results on my 32 bit Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz, gcc 4.5.2: + * Run 100 times: Min-Max(Avg) + #01: Initial insert: 237-257(239) + #02: Initial lookup (match): 180-197(181) + #03: Initial lookup (miss): 171-190(172) + #04: Initial lookup (random): 441-455(446) + #05: Initial delete all: 127-148(128) + #06: Initial re-inserting: 219-298(221) + #07: Deleting first half: 101-109(102) + #08: Adding (a different) half: 159-165(160) + #09: Lookup after half-change (match): 203-216(204) + #10: Lookup after half-change (miss): 217-225(218) + #11: Churn 1: 298-311(300) + #12: Churn 2: 298-318(301) + #13: Churn 3: 301-322(304) + #14: Post-Churn lookup (match): 189-196(190) + #15: Post-Churn lookup (miss): 189-197(191) + #16: Post-Churn lookup (random): 500-531(506) + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* CRITBIT source */ +typedef struct { + void *root; +} critbit0_tree; + +int critbit0_contains(critbit0_tree *t, const char *u); +int critbit0_insert(critbit0_tree *t, const char *u); +int critbit0_delete(critbit0_tree *t, const char *u); +void critbit0_clear(critbit0_tree *t); +int critbit0_allprefixed(critbit0_tree *t, const char *prefix, + int (*handle) (const char *, void *), void *arg); + +#define uint8 uint8_t +#define uint32 uint32_t + +static size_t allocated; + +/*2:*/ + +#include +#include +#include + +#include +#include + +typedef struct{ +void*child[2]; +uint32 byte; +uint8 otherbits; +}critbit0_node; + +/*:2*//*3:*/ + +int +critbit0_contains(critbit0_tree*t,const char*u){ +const uint8*ubytes= (void*)u; +const size_t ulen= strlen(u); +uint8*p= t->root; + +/*4:*/ + +if(!p)return 0; + +/*:4*/ + +/*5:*/ + +while(1&(intptr_t)p){ +critbit0_node*q= (void*)(p-1); +/*6:*/ + +uint8 c= 0; +if(q->bytebyte]; +const int direction= (1+(q->otherbits|c))>>8; + +/*:6*/ + +p= q->child[direction]; +} + +/*:5*/ + +/*7:*/ + +return 0==strcmp(u,(const char*)p); + +/*:7*/ + +} + +/*:3*//*8:*/ + +int critbit0_insert(critbit0_tree*t,const char*u) +{ +const uint8*const ubytes= (void*)u; +const size_t ulen= strlen(u); +uint8*p= t->root; + +/*9:*/ + +if(!p){ +#if 0 +char*x; +int a= posix_memalign((void**)&x,sizeof(void*),ulen+1); +if(a)return 0; +memcpy(x,u,ulen+1); +t->root= x; +#else +t->root = (char *)u; +#endif +return 2; +} + +/*:9*/ + +/*5:*/ + +while(1&(intptr_t)p){ +critbit0_node*q= (void*)(p-1); +/*6:*/ + +uint8 c= 0; +if(q->bytebyte]; +const int direction= (1+(q->otherbits|c))>>8; + +/*:6*/ + +p= q->child[direction]; +} + +/*:5*/ + +/*10:*/ + +/*11:*/ + +uint32 newbyte; +uint32 newotherbits; + +for(newbyte= 0;newbyte>8; + +/*:12*/ + + +/*:10*/ + +/*13:*/ + +/*14:*/ + +critbit0_node*newnode; +if(posix_memalign((void**)&newnode,sizeof(void*),sizeof(critbit0_node)))return 0; +allocated++; +char*x; +#if 0 +if(posix_memalign((void**)&x,sizeof(void*),ulen+1)){ +free(newnode); +return 0; +} +memcpy(x,ubytes,ulen+1); +#else +x = (char *)u; +#endif +newnode->byte= newbyte; +newnode->otherbits= newotherbits; +newnode->child[1-newdirection]= x; + +/*:14*/ + +/*15:*/ + +void**wherep= &t->root; +for(;;){ +uint8*p= *wherep; +if(!(1&(intptr_t)p))break; +critbit0_node*q= (void*)(p-1); +if(q->byte> newbyte)break; +if(q->byte==newbyte&&q->otherbits> newotherbits)break; +uint8 c= 0; +if(q->bytebyte]; +const int direction= (1+(q->otherbits|c))>>8; +wherep= q->child+direction; +} + +newnode->child[newdirection]= *wherep; +*wherep= (void*)(1+(char*)newnode); + +/*:15*/ + + +/*:13*/ + + +return 2; +} + +/*:8*//*16:*/ + +int critbit0_delete(critbit0_tree*t,const char*u){ +const uint8*ubytes= (void*)u; +const size_t ulen= strlen(u); +uint8*p= t->root; +void**wherep= &t->root; +void**whereq= 0; +critbit0_node*q= 0; +int direction= 0; + +/*17:*/ + +if(!p)return 0; + +/*:17*/ + +/*18:*/ + +while(1&(intptr_t)p){ +whereq= wherep; +q= (void*)(p-1); +uint8 c= 0; +if(q->bytebyte]; +direction= (1+(q->otherbits|c))>>8; +wherep= q->child+direction; +p= *wherep; +} + +/*:18*/ + +/*19:*/ + +if(0!=strcmp(u,(const char*)p))return 0; +#if 0 +free(p); +#endif + +/*:19*/ + +/*20:*/ + +if(!whereq){ +t->root= 0; +return 1; +} + +*whereq= q->child[1-direction]; +free(q); +allocated--; +/*:20*/ + + +return 1; +} + +/*:16*//*21:*/ + +static void +traverse(void*top){ +/*22:*/ + +uint8*p= top; + +if(1&(intptr_t)p){ +critbit0_node*q= (void*)(p-1); +traverse(q->child[0]); +traverse(q->child[1]); +free(q); +allocated--; +}else{ +#if 0 +free(p); +#endif +} + +/*:22*/ + +} + +void critbit0_clear(critbit0_tree*t) +{ +if(t->root)traverse(t->root); +t->root= NULL; +} + +/*:21*//*23:*/ + +static int +allprefixed_traverse(uint8*top, +int(*handle)(const char*,void*),void*arg){ +/*26:*/ + +if(1&(intptr_t)top){ +critbit0_node*q= (void*)(top-1); +int direction; +for(direction= 0;direction<2;++direction) +switch(allprefixed_traverse(q->child[direction],handle,arg)){ +case 1:break; +case 0:return 0; +default:return-1; +} +return 1; +} + +/*:26*/ + +/*27:*/ + +return handle((const char*)top,arg);/*:27*/ + +} + +int +critbit0_allprefixed(critbit0_tree*t,const char*prefix, +int(*handle)(const char*,void*),void*arg){ +const uint8*ubytes= (void*)prefix; +const size_t ulen= strlen(prefix); +uint8*p= t->root; +uint8*top= p; +size_t i; + +if(!p)return 1; +/*24:*/ + +while(1&(intptr_t)p){ +critbit0_node*q= (void*)(p-1); +uint8 c= 0; +if(q->bytebyte]; +const int direction= (1+(q->otherbits|c))>>8; +p= q->child[direction]; +if(q->byte