last try on XorLinkList
This commit is contained in:
parent
11bb78c63b
commit
02e0d1d86f
|
@ -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_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_CXX_FLAGS_RELEASE_INIT "${CMAKE_CXX_FLAGS} -Ofast -flto")
|
||||
set(CMAKE_C_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS} -O3 -flto")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE_INIT "${CMAKE_CXX_FLAGS} -O3 -flto")
|
||||
|
||||
set(SOURCES
|
||||
include/hashmap.h
|
||||
|
|
BIN
homework_11
BIN
homework_11
Binary file not shown.
|
@ -1,13 +1,13 @@
|
|||
#define clock_start usize freq=0;\
|
||||
u64 begin=rdtsc_64bits();
|
||||
#define clock_end u64 end=rdtsc_64bits(); \
|
||||
printf(" execute cycle(s) %llu, %zu operation(s) take place!\n",end-begin,freq);
|
||||
#define clock_end u64 end=rdtsc_64bits();
|
||||
// printf(" execute cycle(s) %llu, %zu operation(s) take place!\n",end-begin,freq);
|
||||
|
||||
#define record_start u64 r_begin=rdtsc_64bits();
|
||||
#define record_end(x) output_csv(x,r_begin);
|
||||
// #define record_start u64 r_begin=rdtsc_64bits();
|
||||
// #define record_end(x) output_csv(x,r_begin);
|
||||
|
||||
// #define record_start ;
|
||||
// #define record_end(x) ;
|
||||
#define record_start ;
|
||||
#define record_end(x) ;
|
||||
|
||||
unsigned long long int rdtsc_64bits();
|
||||
void output_csv(char * filename,unsigned long long int old);
|
|
@ -1,3 +1,4 @@
|
|||
#include <stdbool.h>
|
||||
#include "rust.h"
|
||||
|
||||
struct Node{
|
||||
|
@ -8,6 +9,8 @@ struct Node{
|
|||
struct Node* xor_new(void * val);
|
||||
struct Node* xor_next(struct Node* previous,struct Node* current);
|
||||
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);
|
||||
void debug_head(struct Node* head);
|
||||
void * xor_remove(struct Node * previous,struct Node* current);
|
||||
usize xor_count(struct Node* head);
|
5
justfile
5
justfile
|
@ -17,5 +17,10 @@ run:
|
|||
make VERBOSE=1
|
||||
./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:
|
||||
rm -fr CMakeFiles build CMakeCache.txt Makefile cmake_install.cmake *.csv *.profdata *.profraw
|
|
@ -10,18 +10,22 @@ struct Node{
|
|||
__INTPTR_TYPE__ xor_;
|
||||
};
|
||||
|
||||
// shortcut for xor_insert_mid(NULL,NULL,val)
|
||||
struct Node* xor_new(void * val){
|
||||
struct Node* node=malloc(sizeof(struct Node));
|
||||
node->xor_=(__INTPTR_TYPE__)NULL;
|
||||
node->val=val;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// find next node
|
||||
struct Node* xor_next(struct Node* previous,struct Node* current){
|
||||
if(current==NULL) return NULL;
|
||||
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* node=malloc(sizeof(struct 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;
|
||||
}
|
||||
|
||||
// insert randomly, return new node
|
||||
struct Node* xor_insert_front(struct Node* head,void* val){
|
||||
struct Node* next=xor_next(NULL,head);
|
||||
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){
|
||||
// printf("previous: %zu, current: %zu\n",previous,current);
|
||||
struct Node * next=xor_next(previous,current);
|
||||
|
@ -52,7 +78,6 @@ usize xor_count(struct Node* head){
|
|||
usize amount=0;
|
||||
while(current!=NULL){
|
||||
struct Node* next=xor_next(previous,current);
|
||||
// printf("previous: %zu, current: %zu, next: %zu\n",previous,current,next);
|
||||
struct SizedSubmask* mask=current->val;
|
||||
amount++;
|
||||
|
||||
|
@ -62,6 +87,22 @@ usize xor_count(struct Node* head){
|
|||
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()
|
||||
// {
|
||||
// usize my_item=10;
|
||||
|
|
60
src/main.c
60
src/main.c
|
@ -12,72 +12,12 @@ int main()
|
|||
struct State state;
|
||||
state.head=NULL;
|
||||
|
||||
printf("\x1B[34mWelcome to homework 11 (HW11)!\x1B[0m\nDoes it look very familiar?\n\n");
|
||||
|
||||
input(&state);
|
||||
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33minput\x1B[0m.\n");
|
||||
length_distribution(&state);
|
||||
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33mlength_distribution\x1B[0m.\n");
|
||||
segment(&state);
|
||||
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33msegment\x1B[0m.\n");
|
||||
prefix_insert(&state);
|
||||
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33mprefix_insert\x1B[0m.\n");
|
||||
prefix_delete(&state);
|
||||
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33mprefix_delete\x1B[0m.\n");
|
||||
search(&state);
|
||||
printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33msearch\x1B[0m.\n");
|
||||
|
||||
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;
|
||||
// }
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
void panic(char * msg){
|
||||
fprintf(stderr," [\x1B[31mERROR\x1B[0m ] %s\n",msg);
|
||||
exit(1);
|
||||
*NULL;
|
||||
}
|
||||
void log_warn(char * msg){
|
||||
fprintf(stderr," [ \x1B[33mWARN\x1B[0m ] %s\n",msg);
|
||||
|
|
|
@ -27,11 +27,11 @@ usize parse_number(char** cstr_ptr){
|
|||
}
|
||||
|
||||
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){
|
||||
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){
|
||||
|
|
15
src/v1.c
15
src/v1.c
|
@ -8,21 +8,17 @@
|
|||
void input(struct State* state){
|
||||
FILE * table = fopen("routing_table.txt","r");
|
||||
|
||||
struct Node* head=NULL;
|
||||
while(true){
|
||||
char buffer[20]={'\0'};
|
||||
fgets(buffer,20,table);
|
||||
if(*buffer=='\0') break;
|
||||
|
||||
struct SizedSubmask* mask=malloc(sizeof(struct SizedSubmask));
|
||||
// printf("address of new mask: %zu\n",mask);
|
||||
parse_submask(buffer,mask);
|
||||
if(mask<10000)printf("%zu\n",mask);
|
||||
|
||||
if(head==NULL)head=xor_new(mask);
|
||||
else head=xor_insert_mid(NULL,head,mask);
|
||||
state->head=xor_insert_mid(NULL,state->head,mask);
|
||||
}
|
||||
|
||||
state->head=head;
|
||||
}
|
||||
|
||||
void length_distribution(struct State* state){
|
||||
|
@ -36,13 +32,10 @@ void length_distribution(struct State* state){
|
|||
struct SizedSubmask* mask=current->val;
|
||||
lens[mask->len]++;
|
||||
|
||||
// printf("address of scanning mask: %zu\n",mask);
|
||||
|
||||
previous=current;
|
||||
current=next;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
for(usize i=0;i<=32;i++)
|
||||
printf("the number of prefixes with prefix length %zu = %zu\n",i,lens[i]);
|
||||
}
|
84
src/v2.c
84
src/v2.c
|
@ -14,55 +14,89 @@ bool eq(void* a,void* b){
|
|||
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){
|
||||
struct SizedSubmask* mask=a;
|
||||
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>>
|
||||
void segment(struct State* state){
|
||||
printf(" \'d\' is %2d, and empty group are skipped!\n",D);
|
||||
|
||||
state->hashmap=malloc(sizeof(struct HashMap));
|
||||
hash_new(state->hashmap,hasher,eq);
|
||||
|
||||
struct Node* previous=NULL;
|
||||
struct Node* current=state->head;
|
||||
|
||||
state->head=NULL;
|
||||
|
||||
while (current!=NULL){
|
||||
struct SizedSubmask* mask= current->val;
|
||||
struct SizedSubmask* ip=clone_submask(mask);
|
||||
current=xor_remove(NULL,current);
|
||||
if(reduce_submask(mask)){
|
||||
current=xor_remove(previous,current);
|
||||
struct Node* ll=hash_get(state->hashmap,mask);
|
||||
if(ll==NULL){
|
||||
struct Node* ll=xor_new(ip);
|
||||
hash_insert(state->hashmap,mask,ll);
|
||||
}else{
|
||||
xor_insert_front(ll,ip);
|
||||
free(mask);
|
||||
}
|
||||
struct Node* ll=hash_pop(state->hashmap,mask);
|
||||
struct Node* new=xor_insert_mid(NULL,ll,ip);
|
||||
hash_insert(state->hashmap,mask,new);
|
||||
}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);
|
||||
|
||||
printf(" ---> | ");
|
||||
display_ip(current->val);
|
||||
printf(" |");
|
||||
|
||||
previous=current;
|
||||
current=next;
|
||||
free(ip);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
state->head=previous;
|
||||
{
|
||||
printf("--------special group--------\n");
|
||||
|
||||
for(usize i=0;i<B;i++){
|
||||
struct Entry *entry=state->hashmap->entry+i;
|
||||
for(usize j=0;j<entry->size;j++){
|
||||
struct SizedSubmask* mask=entry->list[j].key;
|
||||
struct Node* ll=entry->list[j].val;
|
||||
usize count=xor_count(ll);
|
||||
if(count!=0){
|
||||
printf(" There are %5zu prefix in group %10u (",count,mask->mask.raw);
|
||||
display_submask(mask);
|
||||
printf(")\n");
|
||||
}
|
||||
struct Node* current=state->head;
|
||||
struct Node* previous=NULL;
|
||||
|
||||
while(current!=NULL){
|
||||
struct Node* next=xor_next(previous,current);
|
||||
|
||||
display_ip(current->val);
|
||||
printf("\n");
|
||||
|
||||
previous=current;
|
||||
current=next;
|
||||
}
|
||||
|
||||
printf("-----------------------------\n");
|
||||
}
|
||||
|
||||
}
|
58
src/v3.c
58
src/v3.c
|
@ -13,35 +13,41 @@ bool eq_v3(void* a,void* b){
|
|||
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* previous=NULL;
|
||||
struct Node* current=head;
|
||||
struct Node* next=NULL;
|
||||
while(current!=NULL){
|
||||
struct Node* next=xor_next(previous,current);
|
||||
if(eq(current->val,target)){
|
||||
free(current->val);
|
||||
xor_remove(previous,current);
|
||||
next=xor_remove(previous,current);
|
||||
break;
|
||||
}
|
||||
struct Node* next=xor_next(previous,current);
|
||||
|
||||
previous=current;
|
||||
current=next;
|
||||
}
|
||||
if(previous==NULL) return xor_next(previous,current);
|
||||
return NULL;
|
||||
if(previous==NULL) return next;
|
||||
else return head;
|
||||
}
|
||||
|
||||
bool xor_contain(struct Node* head,void* target,bool (*eq)(void *,void *)){
|
||||
struct Node* previous=NULL;
|
||||
struct Node* current=head;
|
||||
usize round=0;
|
||||
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);
|
||||
if(eq(current->val,target)){
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
previous=current;
|
||||
current=next;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void prefix_insert(struct State* state){
|
||||
|
@ -61,20 +67,11 @@ void prefix_insert(struct State* state){
|
|||
record_start
|
||||
|
||||
if(reduce_submask(mask)){
|
||||
struct Node* ll=hash_get(state->hashmap,mask);
|
||||
if(ll==NULL){
|
||||
struct Node* ll=xor_new(ip);
|
||||
hash_insert(state->hashmap,mask,ll);
|
||||
}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);
|
||||
}
|
||||
|
||||
struct Node* ll=hash_pop(state->hashmap,mask);
|
||||
struct Node* new=xor_insert_mid(NULL,ll,ip);
|
||||
hash_insert(state->hashmap,mask,new);
|
||||
}else state->head=xor_insert_mid(NULL,state->head,ip);
|
||||
|
||||
record_end("prefix_insert.csv")
|
||||
|
||||
freq++;
|
||||
|
@ -93,7 +90,6 @@ void prefix_delete(struct State* state){
|
|||
fgets(buffer,20,table);
|
||||
if(*buffer=='\0') break;
|
||||
|
||||
|
||||
struct SizedSubmask* mask=malloc(sizeof(struct SizedSubmask));
|
||||
parse_submask(buffer,mask);
|
||||
struct SizedSubmask* ip=clone_submask(mask);
|
||||
|
@ -102,19 +98,10 @@ void prefix_delete(struct State* state){
|
|||
|
||||
if(reduce_submask(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);
|
||||
if(new_head==NULL) hash_insert(state->hashmap,mask,ll);
|
||||
else hash_insert(state->hashmap,mask,new_head);
|
||||
if(new_head!=NULL) hash_insert(state->hashmap,mask,new_head);
|
||||
}else{
|
||||
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);
|
||||
if(new_head!=NULL) state->head=new_head;
|
||||
}
|
||||
|
@ -122,9 +109,7 @@ void prefix_delete(struct State* state){
|
|||
|
||||
record_end("prefix_delete.csv")
|
||||
|
||||
drop:
|
||||
free(ip);
|
||||
free(mask);
|
||||
}
|
||||
|
||||
clock_end
|
||||
|
@ -154,11 +139,10 @@ void search(struct State* state){
|
|||
|
||||
record_end("search.csv")
|
||||
|
||||
printf(" submask: ");
|
||||
display_ip(ip);
|
||||
debug_head(ll);
|
||||
|
||||
if (xor_contain(ll,ip,eq_v3)) printf(" can be found among entries\n");
|
||||
else printf(" cannot be found among entries\n");
|
||||
if (xor_contain(ll,ip,eq_v3)) printf("successful\n");
|
||||
else printf("failed\n");
|
||||
|
||||
free(ip);
|
||||
free(mask);
|
||||
|
|
1365
trace_file.txt
1365
trace_file.txt
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue