last try on XorLinkList

This commit is contained in:
eason 2023-12-21 00:47:36 +08:00
parent 11bb78c63b
commit 02e0d1d86f
13 changed files with 149 additions and 1506 deletions

View File

@ -13,8 +13,8 @@ include_directories(/usr/include)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=x86-64-v3" CACHE STRING "Set C Compiler Flags to use x86 feature level V3" FORCE) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=x86-64-v3" CACHE STRING "Set C Compiler Flags to use x86 feature level V3" FORCE)
# set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -I -march=x86-64-v3" CACHE STRING "Set C++ Compiler Flags to use x86 feature level V3" FORCE) # set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -I -march=x86-64-v3" CACHE STRING "Set C++ Compiler Flags to use x86 feature level V3" FORCE)
set(CMAKE_C_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS} -Ofast -flto") set(CMAKE_C_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS} -O3 -flto")
set(CMAKE_CXX_FLAGS_RELEASE_INIT "${CMAKE_CXX_FLAGS} -Ofast -flto") set(CMAKE_CXX_FLAGS_RELEASE_INIT "${CMAKE_CXX_FLAGS} -O3 -flto")
set(SOURCES set(SOURCES
include/hashmap.h include/hashmap.h

Binary file not shown.

View File

@ -1,13 +1,13 @@
#define clock_start usize freq=0;\ #define clock_start usize freq=0;\
u64 begin=rdtsc_64bits(); u64 begin=rdtsc_64bits();
#define clock_end u64 end=rdtsc_64bits(); \ #define clock_end u64 end=rdtsc_64bits();
printf(" execute cycle(s) %llu, %zu operation(s) take place!\n",end-begin,freq); // printf(" execute cycle(s) %llu, %zu operation(s) take place!\n",end-begin,freq);
#define record_start u64 r_begin=rdtsc_64bits(); // #define record_start u64 r_begin=rdtsc_64bits();
#define record_end(x) output_csv(x,r_begin); // #define record_end(x) output_csv(x,r_begin);
// #define record_start ; #define record_start ;
// #define record_end(x) ; #define record_end(x) ;
unsigned long long int rdtsc_64bits(); unsigned long long int rdtsc_64bits();
void output_csv(char * filename,unsigned long long int old); void output_csv(char * filename,unsigned long long int old);

View File

@ -1,3 +1,4 @@
#include <stdbool.h>
#include "rust.h" #include "rust.h"
struct Node{ struct Node{
@ -8,6 +9,8 @@ struct Node{
struct Node* xor_new(void * val); struct Node* xor_new(void * val);
struct Node* xor_next(struct Node* previous,struct Node* current); struct Node* xor_next(struct Node* previous,struct Node* current);
struct Node* xor_insert_front(struct Node* head,void* val); struct Node* xor_insert_front(struct Node* head,void* val);
struct Node* xor_insert_condition(struct Node* head,void* val,bool (*cmp)(void *,void *));
struct Node* xor_insert_mid(struct Node* previous,struct Node* current,void * val); struct Node* xor_insert_mid(struct Node* previous,struct Node* current,void * val);
void debug_head(struct Node* head);
void * xor_remove(struct Node * previous,struct Node* current); void * xor_remove(struct Node * previous,struct Node* current);
usize xor_count(struct Node* head); usize xor_count(struct Node* head);

View File

@ -17,5 +17,10 @@ run:
make VERBOSE=1 make VERBOSE=1
./homework_11 ./homework_11
mem-test:
cmake -DCMAKE_C_FLAGS="-fsanitize=address -fstandalone-debug" -DCMAKE_BUILD_TYPE=Debug -C clang-cmakeinit.cmake .
make VERBOSE=1
./homework_11
clean: clean:
rm -fr CMakeFiles build CMakeCache.txt Makefile cmake_install.cmake *.csv *.profdata *.profraw rm -fr CMakeFiles build CMakeCache.txt Makefile cmake_install.cmake *.csv *.profdata *.profraw

View File

@ -10,18 +10,22 @@ struct Node{
__INTPTR_TYPE__ xor_; __INTPTR_TYPE__ xor_;
}; };
// shortcut for xor_insert_mid(NULL,NULL,val)
struct Node* xor_new(void * val){ struct Node* xor_new(void * val){
struct Node* node=malloc(sizeof(struct Node)); struct Node* node=malloc(sizeof(struct Node));
node->xor_=(__INTPTR_TYPE__)NULL; node->xor_=(__INTPTR_TYPE__)NULL;
node->val=val; node->val=val;
return node; return node;
} }
// find next node
struct Node* xor_next(struct Node* previous,struct Node* current){ struct Node* xor_next(struct Node* previous,struct Node* current){
if(current==NULL) return NULL; if(current==NULL) return NULL;
return (struct Node*)((current->xor_)^((__INTPTR_TYPE__)previous)); return (struct Node*)((current->xor_)^((__INTPTR_TYPE__)previous));
} }
// insert node at middle, return new node
struct Node* xor_insert_mid(struct Node* previous,struct Node* current,void * val){ struct Node* xor_insert_mid(struct Node* previous,struct Node* current,void * val){
struct Node* node=malloc(sizeof(struct Node)); struct Node* node=malloc(sizeof(struct Node));
if(previous!=NULL)previous->xor_^=((__INTPTR_TYPE__)current)^((__INTPTR_TYPE__)node); if(previous!=NULL)previous->xor_^=((__INTPTR_TYPE__)current)^((__INTPTR_TYPE__)node);
@ -31,11 +35,33 @@ struct Node* xor_insert_mid(struct Node* previous,struct Node* current,void * va
return node; return node;
} }
// insert randomly, return new node
struct Node* xor_insert_front(struct Node* head,void* val){ struct Node* xor_insert_front(struct Node* head,void* val){
struct Node* next=xor_next(NULL,head); struct Node* next=xor_next(NULL,head);
return xor_insert_mid(head,next,val); return xor_insert_mid(head,next,val);
} }
// insert after the element that make cmp return true, insert at front if not found, return new head
struct Node* xor_insert_condition(struct Node* head,void* val,bool (*cmp)(void *,void *)){
if(head==NULL) return xor_new(val);
struct Node* previous=NULL;
struct Node* current=head;
usize amount=0;
while(current!=NULL){
struct Node* next=xor_next(previous,current);
if(!cmp(val,current->val)){
xor_insert_mid(current,next,val);
return head;
}
previous=current;
current=next;
}
return xor_insert_mid(NULL,head,val);
}
// remove current, return next
struct Node * xor_remove(struct Node * previous,struct Node* current){ struct Node * xor_remove(struct Node * previous,struct Node* current){
// printf("previous: %zu, current: %zu\n",previous,current); // printf("previous: %zu, current: %zu\n",previous,current);
struct Node * next=xor_next(previous,current); struct Node * next=xor_next(previous,current);
@ -52,7 +78,6 @@ usize xor_count(struct Node* head){
usize amount=0; usize amount=0;
while(current!=NULL){ while(current!=NULL){
struct Node* next=xor_next(previous,current); struct Node* next=xor_next(previous,current);
// printf("previous: %zu, current: %zu, next: %zu\n",previous,current,next);
struct SizedSubmask* mask=current->val; struct SizedSubmask* mask=current->val;
amount++; amount++;
@ -62,6 +87,22 @@ usize xor_count(struct Node* head){
return amount; return amount;
} }
void debug_head(struct Node* head){
struct Node* previous=NULL;
struct Node* current=head;
printf("start of address:");
while(current!=NULL){
struct Node* next=xor_next(previous,current);
struct SizedSubmask* mask=current->val;
printf("%zu ,",current);
previous=current;
current=next;
}
printf("\n");
}
// int test() // int test()
// { // {
// usize my_item=10; // usize my_item=10;

View File

@ -12,72 +12,12 @@ int main()
struct State state; struct State state;
state.head=NULL; state.head=NULL;
printf("\x1B[34mWelcome to homework 11 (HW11)!\x1B[0m\nDoes it look very familiar?\n\n");
input(&state); input(&state);
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33minput\x1B[0m.\n");
length_distribution(&state); length_distribution(&state);
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33mlength_distribution\x1B[0m.\n");
segment(&state); segment(&state);
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33msegment\x1B[0m.\n");
prefix_insert(&state); prefix_insert(&state);
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33mprefix_insert\x1B[0m.\n");
prefix_delete(&state); prefix_delete(&state);
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33mprefix_delete\x1B[0m.\n");
search(&state); search(&state);
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33msearch\x1B[0m.\n");
return 0; return 0;
} }
// struct Point{
// usize x;
// usize y;
// };
// bool eqa(void* x,void* y){
// struct Point* a=x;
// struct Point* b=y;
// return (a->x==b->x)&&(a->y==b->y);
// }
// usize hashera(void* a){
// struct Point* p=a;
// return (p->x)+(p->y)/2;
// }
// int main()
// {
// struct HashMap map;
// hash_new(&map,hashera,eqa);
// // struct Point pa;
// // usize va=2;
// // pa.x=2;
// // pa.y=7;
// // struct Point pb;
// // usize vb=3;
// // pb.x=1;
// // pb.y=9;
// // hash_insert(&map,&pa,&va);
// // hash_insert(&map,&pb,&vb);
// // printf("pa has address of %zu\npb has address of %zu\n",&pa,&pb);
// // usize * assert=hash_get(&map,&pb);
// // printf("address: %zu\n",assert);
// // printf("value: %zu\n",*assert);
// for(usize i=0;i<B;i++){
// struct Entry *entry=map.entry+i;
// printf("entry size: %zu\n",entry->size);
// // for(usize j=0;j<entry[i].size;j++){
// // struct SizedSubmask* mask=entry->list[j].key;
// // struct Node* ll=entry->list[j].val;
// // // usize count=xor_count(ll);
// // printf("one entry\n");
// // // printf("There are _ prefix in group %u\n",mask->mask.raw);
// // }
// }
// return 0;
// }

View File

@ -12,7 +12,7 @@
void panic(char * msg){ void panic(char * msg){
fprintf(stderr," [\x1B[31mERROR\x1B[0m ] %s\n",msg); fprintf(stderr," [\x1B[31mERROR\x1B[0m ] %s\n",msg);
exit(1); *NULL;
} }
void log_warn(char * msg){ void log_warn(char * msg){
fprintf(stderr," [ \x1B[33mWARN\x1B[0m ] %s\n",msg); fprintf(stderr," [ \x1B[33mWARN\x1B[0m ] %s\n",msg);

View File

@ -27,11 +27,11 @@ usize parse_number(char** cstr_ptr){
} }
usize display_submask(struct SizedSubmask *mask){ usize display_submask(struct SizedSubmask *mask){
printf("%3hd.%hd.%hd.%hd/%zu",mask->mask.mask[3],mask->mask.mask[2],mask->mask.mask[1],mask->mask.mask[0],mask->len); printf("%hd.%hd.%hd.%hd/%zu",mask->mask.mask[3],mask->mask.mask[2],mask->mask.mask[1],mask->mask.mask[0],mask->len);
} }
usize display_ip(struct SizedSubmask *mask){ usize display_ip(struct SizedSubmask *mask){
printf("%3hd.%3hd.%3hd.%3hd",mask->mask.mask[3],mask->mask.mask[2],mask->mask.mask[1],mask->mask.mask[0]); printf("%hd.%hd.%hd.%hd",mask->mask.mask[3],mask->mask.mask[2],mask->mask.mask[1],mask->mask.mask[0]);
} }
void parse_submask(char* cstr, struct SizedSubmask *mask){ void parse_submask(char* cstr, struct SizedSubmask *mask){

View File

@ -8,21 +8,17 @@
void input(struct State* state){ void input(struct State* state){
FILE * table = fopen("routing_table.txt","r"); FILE * table = fopen("routing_table.txt","r");
struct Node* head=NULL;
while(true){ while(true){
char buffer[20]={'\0'}; char buffer[20]={'\0'};
fgets(buffer,20,table); fgets(buffer,20,table);
if(*buffer=='\0') break; if(*buffer=='\0') break;
struct SizedSubmask* mask=malloc(sizeof(struct SizedSubmask)); struct SizedSubmask* mask=malloc(sizeof(struct SizedSubmask));
// printf("address of new mask: %zu\n",mask);
parse_submask(buffer,mask); parse_submask(buffer,mask);
if(mask<10000)printf("%zu\n",mask);
if(head==NULL)head=xor_new(mask); state->head=xor_insert_mid(NULL,state->head,mask);
else head=xor_insert_mid(NULL,head,mask);
} }
state->head=head;
} }
void length_distribution(struct State* state){ void length_distribution(struct State* state){
@ -36,13 +32,10 @@ void length_distribution(struct State* state){
struct SizedSubmask* mask=current->val; struct SizedSubmask* mask=current->val;
lens[mask->len]++; lens[mask->len]++;
// printf("address of scanning mask: %zu\n",mask);
previous=current; previous=current;
current=next; current=next;
} }
for(usize i=0;i<=32;i++){ for(usize i=0;i<=32;i++)
if(lens[i]!=0) printf(" There are %5zu prefix which have prefix len of %2zu\n",lens[i],i); printf("the number of prefixes with prefix length %zu = %zu\n",i,lens[i]);
}
} }

View File

@ -14,55 +14,89 @@ bool eq(void* a,void* b){
return mask_a->mask.raw==mask_b->mask.raw; return mask_a->mask.raw==mask_b->mask.raw;
} }
bool cmp(void* a,void* b){
struct SizedSubmask* mask_a=a;
struct SizedSubmask* mask_b=b;
return mask_a->mask.raw>mask_b->mask.raw;// for debug
}
usize hasher(void* a){ usize hasher(void* a){
struct SizedSubmask* mask=a; struct SizedSubmask* mask=a;
return mask->mask.raw; return mask->mask.raw;
} }
void print_binary(usize j){
for(size_t i=1;i<=D;i++){
printf("%s",(0==(j&(1<<(D-i))))?"0":"1");
}
}
// std::collections::HashMap<SizedSubmask,XorLinklist<SizeSubmask>> // std::collections::HashMap<SizedSubmask,XorLinklist<SizeSubmask>>
void segment(struct State* state){ void segment(struct State* state){
printf(" \'d\' is %2d, and empty group are skipped!\n",D);
state->hashmap=malloc(sizeof(struct HashMap)); state->hashmap=malloc(sizeof(struct HashMap));
hash_new(state->hashmap,hasher,eq); hash_new(state->hashmap,hasher,eq);
struct Node* previous=NULL;
struct Node* current=state->head; struct Node* current=state->head;
state->head=NULL;
while (current!=NULL){ while (current!=NULL){
struct SizedSubmask* mask= current->val; struct SizedSubmask* mask= current->val;
struct SizedSubmask* ip=clone_submask(mask); struct SizedSubmask* ip=clone_submask(mask);
current=xor_remove(NULL,current);
if(reduce_submask(mask)){ if(reduce_submask(mask)){
current=xor_remove(previous,current); struct Node* ll=hash_pop(state->hashmap,mask);
struct Node* ll=hash_get(state->hashmap,mask); struct Node* new=xor_insert_mid(NULL,ll,ip);
if(ll==NULL){ hash_insert(state->hashmap,mask,new);
struct Node* ll=xor_new(ip);
hash_insert(state->hashmap,mask,ll);
}else{
xor_insert_front(ll,ip);
free(mask);
}
}else{ }else{
state->head=xor_insert_condition(state->head,ip,cmp);
free(mask);
}
}
// C suck! we need iterator!
for(usize i=0;i<(1<<D);i++){
struct SizedSubmask mask;
mask.len=D;
mask.mask.raw=i<<(32-D);
printf("| ");
print_binary(i);
printf(" |");
struct Node* current=hash_get(state->hashmap,&mask);
struct Node* previous=NULL;
while(current!=NULL){
struct Node* next=xor_next(previous,current); struct Node* next=xor_next(previous,current);
printf(" ---> | ");
display_ip(current->val);
printf(" |");
previous=current; previous=current;
current=next; current=next;
free(ip);
} }
printf("\n");
} }
state->head=previous; {
printf("--------special group--------\n");
for(usize i=0;i<B;i++){ struct Node* current=state->head;
struct Entry *entry=state->hashmap->entry+i; struct Node* previous=NULL;
for(usize j=0;j<entry->size;j++){
struct SizedSubmask* mask=entry->list[j].key; while(current!=NULL){
struct Node* ll=entry->list[j].val; struct Node* next=xor_next(previous,current);
usize count=xor_count(ll);
if(count!=0){ display_ip(current->val);
printf(" There are %5zu prefix in group %10u (",count,mask->mask.raw); printf("\n");
display_submask(mask);
printf(")\n"); previous=current;
} current=next;
} }
printf("-----------------------------\n");
} }
} }

View File

@ -13,35 +13,41 @@ bool eq_v3(void* a,void* b){
return mask_a->mask.raw==mask_b->mask.raw; return mask_a->mask.raw==mask_b->mask.raw;
} }
// remove match element, return new head
struct Node* xor_remove_match(struct Node* head,void* target,bool (*eq)(void *,void *)){ struct Node* xor_remove_match(struct Node* head,void* target,bool (*eq)(void *,void *)){
struct Node* previous=NULL; struct Node* previous=NULL;
struct Node* current=head; struct Node* current=head;
struct Node* next=NULL;
while(current!=NULL){ while(current!=NULL){
struct Node* next=xor_next(previous,current);
if(eq(current->val,target)){ if(eq(current->val,target)){
free(current->val); free(current->val);
xor_remove(previous,current); next=xor_remove(previous,current);
break; break;
} }
struct Node* next=xor_next(previous,current);
previous=current; previous=current;
current=next; current=next;
} }
if(previous==NULL) return xor_next(previous,current); if(previous==NULL) return next;
return NULL; else return head;
} }
bool xor_contain(struct Node* head,void* target,bool (*eq)(void *,void *)){ bool xor_contain(struct Node* head,void* target,bool (*eq)(void *,void *)){
struct Node* previous=NULL; struct Node* previous=NULL;
struct Node* current=head; struct Node* current=head;
usize round=0;
while(current!=NULL){ while(current!=NULL){
// if(current<((usize)100000)) break;
// printf("current: %zu, previous: %zu, round: %zu\n",current,previous, ++round);
struct Node* next=xor_next(previous,current); struct Node* next=xor_next(previous,current);
if(eq(current->val,target)){ if(eq(current->val,target)){
return false; return true;
} }
previous=current; previous=current;
current=next; current=next;
} }
return true; return false;
} }
void prefix_insert(struct State* state){ void prefix_insert(struct State* state){
@ -61,20 +67,11 @@ void prefix_insert(struct State* state){
record_start record_start
if(reduce_submask(mask)){ if(reduce_submask(mask)){
struct Node* ll=hash_get(state->hashmap,mask); struct Node* ll=hash_pop(state->hashmap,mask);
if(ll==NULL){ struct Node* new=xor_insert_mid(NULL,ll,ip);
struct Node* ll=xor_new(ip); hash_insert(state->hashmap,mask,new);
hash_insert(state->hashmap,mask,ll); }else state->head=xor_insert_mid(NULL,state->head,ip);
}else{
xor_insert_front(ll,ip);
free(mask);
}
}else{
free(ip);
if(state->head==NULL)state->head=xor_new(mask);
else state->head=xor_insert_mid(NULL,state->head,mask);
}
record_end("prefix_insert.csv") record_end("prefix_insert.csv")
freq++; freq++;
@ -93,7 +90,6 @@ void prefix_delete(struct State* state){
fgets(buffer,20,table); fgets(buffer,20,table);
if(*buffer=='\0') break; if(*buffer=='\0') break;
struct SizedSubmask* mask=malloc(sizeof(struct SizedSubmask)); struct SizedSubmask* mask=malloc(sizeof(struct SizedSubmask));
parse_submask(buffer,mask); parse_submask(buffer,mask);
struct SizedSubmask* ip=clone_submask(mask); struct SizedSubmask* ip=clone_submask(mask);
@ -102,19 +98,10 @@ void prefix_delete(struct State* state){
if(reduce_submask(mask)){ if(reduce_submask(mask)){
struct Node* ll=hash_pop(state->hashmap,mask); struct Node* ll=hash_pop(state->hashmap,mask);
if(ll==NULL) {
log_warn("removal fail, cannot find index!");
goto drop;
}
struct Node* new_head=xor_remove_match(ll,ip,eq_v3); struct Node* new_head=xor_remove_match(ll,ip,eq_v3);
if(new_head==NULL) hash_insert(state->hashmap,mask,ll); if(new_head!=NULL) hash_insert(state->hashmap,mask,new_head);
else hash_insert(state->hashmap,mask,new_head);
}else{ }else{
struct Node* ll=state->head; struct Node* ll=state->head;
if(ll==NULL) {
log_warn("removal fail, cannot find index!");
goto drop;
}
struct Node* new_head=xor_remove_match(ll,ip,eq_v3); struct Node* new_head=xor_remove_match(ll,ip,eq_v3);
if(new_head!=NULL) state->head=new_head; if(new_head!=NULL) state->head=new_head;
} }
@ -122,9 +109,7 @@ void prefix_delete(struct State* state){
record_end("prefix_delete.csv") record_end("prefix_delete.csv")
drop:
free(ip); free(ip);
free(mask);
} }
clock_end clock_end
@ -154,11 +139,10 @@ void search(struct State* state){
record_end("search.csv") record_end("search.csv")
printf(" submask: "); debug_head(ll);
display_ip(ip);
if (xor_contain(ll,ip,eq_v3)) printf(" can be found among entries\n"); if (xor_contain(ll,ip,eq_v3)) printf("successful\n");
else printf(" cannot be found among entries\n"); else printf("failed\n");
free(ip); free(ip);
free(mask); free(mask);

File diff suppressed because it is too large Load Diff