before next stage

This commit is contained in:
eason
2023-12-20 18:54:24 +08:00
commit c6f08be676
38 changed files with 183324 additions and 0 deletions

24
src/clock.c Normal file
View File

@ -0,0 +1,24 @@
#include "rust.h"
#include <stdio.h>
#include <stdlib.h>
unsigned long long int rdtsc_64bits()//64-bit
{
unsigned long long int x;
unsigned a, d;
__asm__ volatile("rdtsc" : "=a" (a), "=d" (d));
return ((unsigned long long)a) | (((unsigned long long)d) << 32);;
}
void output_csv(char * filename,u64 old){
u64 new=rdtsc_64bits();
FILE* file = fopen(filename , "a");
fprintf(file, "%ld,",new-old);
fflush(file);
fclose(file);
}

110
src/hashmap.c Normal file
View File

@ -0,0 +1,110 @@
#include <stdbool.h>
#include <stdio.h>
#include "rust.h"
#define B 100
struct Entries{
void* key;
void* val;
};
struct Entry{
usize size;
usize cap;
struct Entries* list;
};
struct HashMap{
struct Entry entry[B];
usize (*hasher)(void *);
bool (*eq)(void *,void *);
};
//.please return '1' in clang, because only exactly '1' are guarantee to be true,
// value other than '0' and '1' in bool can cause UB.
void hash_new(struct HashMap* map,usize (*hasher)(void *), bool (*eq)(void *,void *)){
map->eq=eq;
map->hasher=hasher;
for(usize i=0;i<B;i++){
map->entry[i].cap=1;
map->entry[i].list=malloc(sizeof(struct Entries));
map->entry[i].size=0;
}
}
void hash_insert(struct HashMap* map,void* key,void* val){
usize hashed=map->hasher(key);
struct Entry* entry=map->entry+(hashed%B);
entry->list[entry->size].key=key;
entry->list[entry->size++].val=val;
if(entry->size==entry->cap){
entry->cap*=2;
entry->list=realloc(entry->list,sizeof(struct Entries)*entry->cap);
}
}
void* hash_get(struct HashMap* map,void* key){
usize hashed=map->hasher(key);
struct Entry* entry=map->entry+(hashed%B);
for(size_t i=0;i<(entry->size);i++){
if (map->eq(entry->list[i].key,key)){
return entry->list[i].val;
}
}
return NULL;
}
void* hash_pop(struct HashMap* map,void* key){
usize hashed=map->hasher(key);
struct Entry* entry=map->entry+(hashed%B);
for(size_t i=0;i<(entry->size);i++){
if (map->eq(entry->list[i].key,key)){
void* tmp=entry->list[i].val;
usize tail=(--entry->size);
entry->list[i]=entry->list[tail];
return entry->list[i].val;
}
}
return NULL;
}
// struct Point{
// usize x;
// usize y;
// };
// bool eq(void* x,void* y){
// struct Point* a=x;
// struct Point* b=y;
// return (a->x==b->x)&&(a->y==b->y);
// }
// usize hasher(void* a){
// struct Point* p=a;
// return (p->x)+(p->y)/2;
// }
// int test()
// {
// struct HashMap map;
// 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_new(&map,hasher,eq);
// 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);
// return 0;
// }

78
src/linklist.c Normal file
View File

@ -0,0 +1,78 @@
// https://github.com/Seppel3210/rust-xor_-list
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "rust.h"
struct Node{
void* val;
__INTPTR_TYPE__ xor_;
};
struct Node* xor_new(void * val){
struct Node* node=malloc(sizeof(struct Node));
node->xor_=(__INTPTR_TYPE__)NULL;
node->val=val;
return node;
}
struct Node* xor_next(struct Node* previous,struct Node* current){
if(current==NULL) return NULL;
return (struct Node*)((current->xor_)^((__INTPTR_TYPE__)previous));
}
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);
if(current!=NULL)current->xor_^=((__INTPTR_TYPE__)previous)^((__INTPTR_TYPE__)node);
node->val=val;
node->xor_=((__INTPTR_TYPE__)current)^((__INTPTR_TYPE__)previous);
return 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);
}
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);
if(previous!=NULL) previous->xor_^=(__INTPTR_TYPE__)current^(__INTPTR_TYPE__)next;
if(next!=NULL) next->xor_^=(__INTPTR_TYPE__)current^(__INTPTR_TYPE__)previous;
free(current);
return next;
}
usize xor_count(struct Node* head){
struct Node* previous=NULL;
struct Node* current=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++;
previous=current;
current=next;
}
return amount;
}
// int test()
// {
// usize my_item=10;
// struct Node* first=xor_new(&my_item);
// struct Node* second=xor_insert(NULL,first,&my_item);
// struct Node* third=xor_insert(second,second,&my_item);
// usize* my_item_ptr=xor_remove(first,second);
// printf("%zu",*my_item_ptr);
// return 0;
// }

83
src/main.c Normal file
View File

@ -0,0 +1,83 @@
#include <stdio.h>
#include <stdbool.h>
#include "linklist.h"
#include "hashmap.h"
#include "v1.h"
#include "v2.h"
#include "v3.h"
#include "rust.h"
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;
// }

19
src/rust.c Normal file
View File

@ -0,0 +1,19 @@
#include <stdlib.h>
#include <stdio.h>
#define u8 unsigned char
#define u16 unsigned short int
#define u32 unsigned int
#define u64 unsigned long int
#define i8 char
#define i16 short int
#define i32 int
#define i64 long int
#define usize size_t
void panic(char * msg){
fprintf(stderr," [\x1B[31mERROR\x1B[0m ] %s\n",msg);
exit(1);
}
void log_warn(char * msg){
fprintf(stderr," [ \x1B[33mWARN\x1B[0m ] %s\n",msg);
}

81
src/state.c Normal file
View File

@ -0,0 +1,81 @@
#include <stdio.h>
#include <stdlib.h>
#include "rust.h"
#include "linklist.h"
#include "hashmap.h"
#define D 8
union Submask
{
u8 mask[4];
u32 raw;
};
struct SizedSubmask
{
union Submask mask;
usize len;
};
usize parse_number(char** cstr_ptr){
usize tmp=0;
while((**cstr_ptr<='9')&&(**cstr_ptr>='0')){
tmp=tmp*10+(usize)(**cstr_ptr-'0');
(*cstr_ptr)++;
}
return tmp;
}
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);
}
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]);
}
void parse_submask(char* cstr, struct SizedSubmask *mask){
for (usize i=0;i<4;i++){
mask->mask.mask[3-i]=(u8)parse_number(&cstr);
cstr++;
}
if(*cstr<'0'||*cstr>'9'){
usize i=0;
for (i=0;i<4;i++)
if(mask->mask.mask[3-i]==0)break;
mask->len=i*8;
}else mask->len=parse_number(&cstr);
}
struct SizedSubmask* clone_submask(struct SizedSubmask *mask){
struct SizedSubmask *new=malloc(sizeof(struct SizedSubmask));
new->len=mask->len;
new->mask.raw=mask->mask.raw;
return new;
}
bool reduce_submask(struct SizedSubmask* source){
if(source->len<D)return false;
u32 mask=source->mask.raw;
source->len=D;
source->mask.raw=((mask>>(32-D))<<(32-D));
return true;
}
struct State{
struct Node* head;
struct HashMap hashmap;
};
// int test()
// {
// char *example = "192.168.1.1/24";
// struct SizedSubmask mask;
// parse_submask(example, &mask);
// printf("CIDR: %u.%u.%u.%u/%u\n", mask.mask.mask[3], mask.mask.mask[2], mask.mask.mask[1], mask.mask.mask[0],mask.len);
// return 0;
// }

48
src/v1.c Normal file
View File

@ -0,0 +1,48 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "linklist.h"
#include "state.h"
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(head==NULL)head=xor_new(mask);
else head=xor_insert_mid(NULL,head,mask);
}
state->head=head;
}
void length_distribution(struct State* state){
usize lens[33]={0};
struct Node* previous=NULL;
struct Node* current=state->head;
while(current!=NULL){
struct Node* next=xor_next(previous,current);
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);
}
}

68
src/v2.c Normal file
View File

@ -0,0 +1,68 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "linklist.h"
#include "hashmap.h"
#include "state.h"
#define D 8
// assume there is no prefix like this 192.0.0.0/1, this is a strange prefix,
// because 192.0.0.0 has first two bit set, but is has submask smaller than two
bool eq(void* a,void* b){
struct SizedSubmask* mask_a=a;
struct SizedSubmask* mask_b=b;
return mask_a->mask.raw==mask_b->mask.raw;
}
usize hasher(void* a){
struct SizedSubmask* mask=a;
return mask->mask.raw;
}
// 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;
while (current!=NULL){
struct SizedSubmask* mask= current->val;
struct SizedSubmask* ip=clone_submask(mask);
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);
}
}else{
struct Node* next=xor_next(previous,current);
previous=current;
current=next;
free(ip);
}
}
state->head=previous;
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");
}
}
}
}

168
src/v3.c Normal file
View File

@ -0,0 +1,168 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "linklist.h"
#include "state.h"
#include "hashmap.h"
#include "clock.h"
bool eq_v3(void* a,void* b){
struct SizedSubmask* mask_a=a;
struct SizedSubmask* mask_b=b;
return mask_a->mask.raw==mask_b->mask.raw;
}
struct Node* xor_remove_match(struct Node* head,void* target,bool (*eq)(void *,void *)){
struct Node* previous=NULL;
struct Node* current=head;
while(current!=NULL){
struct Node* next=xor_next(previous,current);
if(eq(current->val,target)){
free(current->val);
xor_remove(previous,current);
break;
}
previous=current;
current=next;
}
if(previous==NULL) return xor_next(previous,current);
return NULL;
}
bool xor_contain(struct Node* head,void* target,bool (*eq)(void *,void *)){
struct Node* previous=NULL;
struct Node* current=head;
while(current!=NULL){
struct Node* next=xor_next(previous,current);
if(eq(current->val,target)){
return false;
}
previous=current;
current=next;
}
return true;
}
void prefix_insert(struct State* state){
FILE * table = fopen("inserted_prefixes.txt","r");
clock_start
while(true){
char buffer[20]={'\0'};
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);
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);
}
record_end("prefix_insert.csv")
freq++;
}
clock_end
}
void prefix_delete(struct State* state){
FILE * table = fopen("deleted_prefixes.txt","r");
clock_start
while(true){
char buffer[20]={'\0'};
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);
record_start
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);
}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;
}
freq++;
record_end("prefix_delete.csv")
drop:
free(ip);
free(mask);
}
clock_end
}
void search(struct State* state){
FILE * table = fopen("trace_file.txt","r");
clock_start
while(true){
char buffer[20]={'\0'};
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);
record_start
struct Node* ll;
if(reduce_submask(mask))ll=hash_get(state->hashmap,mask);
else ll=state->head;
freq++;
record_end("search.csv")
printf(" submask: ");
display_ip(ip);
if (xor_contain(ll,ip,eq_v3)) printf(" can be found among entries\n");
else printf(" cannot be found among entries\n");
free(ip);
free(mask);
}
clock_end
}