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

60
.clang-format Normal file
View File

@ -0,0 +1,60 @@
---
Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Allman
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 120
CommentPragmas: ""
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [foreach, Q_FOREACH, BOOST_FOREACH]
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 3
NamespaceIndentation: All
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: Never

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
/cmake_install.cmake
/build
/.vscode
/CMakeFiles
/Makefile
/CMakeCache.txt
*.profdata
*.profraw

44
CMakeLists.txt Normal file
View File

@ -0,0 +1,44 @@
cmake_minimum_required(VERSION 3.5)
project (homework_11)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message("Setting build type to 'Debug' as none was specified.")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
endif()
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(SOURCES
include/hashmap.h
include/state.h
include/linklist.h
include/clock.h
include/rust.h
include/v1.h
include/v2.h
include/v3.h
src/hashmap.c
src/state.c
src/linklist.c
src/clock.c
src/rust.c
src/v1.c
src/v2.c
src/v3.c
src/main.c
)
add_executable(homework_11 ${SOURCES})
target_include_directories(
homework_11
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
)

6
clang-cmakeinit.cmake Normal file
View File

@ -0,0 +1,6 @@
# set(TOOLCHAIN_PREFIX "x86_64-w64-mingw32-")
set(CMAKE_C_COMPILER "clang" CACHE STRING "clang compiler" FORCE)
set(CMAKE_CXX_COMPILER "clang++" CACHE STRING "clang++ compiler" FORCE)
# set(CMAKE_MAKE_PROGRAM "mingw32-make" CACHE STRING "make command" FORCE)

4163
deleted_prefixes.txt Normal file

File diff suppressed because it is too large Load Diff

14
doc/explain.md Normal file
View File

@ -0,0 +1,14 @@
# Chart with suffix -1.png
In those three chart, we know that they all have similar instruction, the distribution wasn't similar to linklist, but the average time is.
It's because two reason, one cause high baseline time, another is the data structure I use.
The first reason which cause high baseline time is bad IO optimization, It read from file for every prefix, even worse, I open file to write the chart before calling `usize end=rdtsc_64bits();`, which block.
The second reason is the addition of HashMap, rather than placing linklist(xor linklist) in vector(slice), I placed linklist in a custom hashmap, moreover, when the key is missing in the hashmap, the `hash_get()` function iterating all elements in hashmap, and hash collusion was discovered in one of the bucket, so there are several operation took significantly more time.
# Chart with suffix -2.png
After optimize some IO, I get correct result for combination of hashmap and linklist.

BIN
doc/prefix_delete-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
doc/prefix_delete-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
doc/prefix_insert-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
doc/prefix_insert-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
doc/search-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
doc/search-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
homework_11 Executable file

Binary file not shown.

13
include/clock.h Normal file
View File

@ -0,0 +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 record_start u64 r_begin=rdtsc_64bits();
#define record_end(x) output_csv(x,r_begin);
// #define record_start ;
// #define record_end(x) ;
unsigned long long int rdtsc_64bits();
void output_csv(char * filename,unsigned long long int old);

22
include/hashmap.h Normal file
View File

@ -0,0 +1,22 @@
#include <stdbool.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 *);
};
void hash_new(struct HashMap* map,usize (*hasher)(void *), bool (*eq)(void *,void *));
void hash_insert(struct HashMap* map,void* key,void* val);
void* hash_get(struct HashMap* map,void* key);
void* hash_pop(struct HashMap* map,void* key);

13
include/linklist.h Normal file
View File

@ -0,0 +1,13 @@
#include "rust.h"
struct Node{
void* val;
__INTPTR_TYPE__ xor_;
};
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_mid(struct Node* previous,struct Node* current,void * val);
void * xor_remove(struct Node * previous,struct Node* current);
usize xor_count(struct Node* head);

13
include/rust.h Normal file
View File

@ -0,0 +1,13 @@
#include <stdlib.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);
void log_warn(char * msg);

26
include/state.h Normal file
View File

@ -0,0 +1,26 @@
#include "rust.h"
struct HashMap;
union Submask
{
u8 mask[4];
u32 raw;
};
struct SizedSubmask
{
union Submask mask;
usize len;
};
usize display_submask(struct SizedSubmask *mask);
usize display_ip(struct SizedSubmask *mask);
void parse_submask(char* cstr, struct SizedSubmask *mask);
struct SizedSubmask* clone_submask(struct SizedSubmask *mask);
bool reduce_submask(struct SizedSubmask* source);
struct State{
struct Node* head;
struct HashMap* hashmap;
};

2
include/v1.h Normal file
View File

@ -0,0 +1,2 @@
void input(struct State* state);
void length_distribution(struct State* state);

3
include/v2.h Normal file
View File

@ -0,0 +1,3 @@
#include "state.h"
void segment(struct State* state);

3
include/v3.h Normal file
View File

@ -0,0 +1,3 @@
void prefix_insert(struct State* state);
void prefix_delete(struct State* state);
void search(struct State* state);

4455
inserted_prefixes.txt Normal file

File diff suppressed because it is too large Load Diff

21
justfile Normal file
View File

@ -0,0 +1,21 @@
profile:
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-fprofile-instr-generate" -DCMAKE_CXX_FLAGS="-fprofile-instr-generate" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -C clang-cmakeinit.cmake .
make
LLVM_PROFILE_FILE="homework_11.profraw" ./homework_11
release-profile:
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-fprofile-instr-use=homework_11.profdata" -DCMAKE_CXX_FLAGS="-fprofile-instr-use=homework_11.profdata" -C clang-cmakeinit.cmake .
llvm-profdata merge -output=homework_11.profdata homework_11.profraw
make VERBOSE=1
release:
cmake -C clang-cmakeinit.cmake .
make
run:
cmake -DCMAKE_C_FLAGS="-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

1
prefix_delete.csv Normal file

File diff suppressed because one or more lines are too long

1
prefix_insert.csv Normal file

File diff suppressed because one or more lines are too long

55
readme.md Normal file
View File

@ -0,0 +1,55 @@
# homework 11 (HW11)
## Quick Start
1. Get a computer with x86 feature level v3
2. Run `./homework_11`
3. See `./Doc` to skip running the actual program
## Setup
1. install `clang` and `just`
2. run `just profile`
3. run `just release-profile`
4. run `./homework_11`
## Shellshot?~~Screenshot~~
```console
Welcome to homework 11 (HW11)!
Does it look very familiar?
[ OK ] Reached target input.
There are 1 prefix which have prefix len of 3
There are 1 prefix which have prefix len of 5
There are 3 prefix which have prefix len of 6
There are 4 prefix which have prefix len of 7
There are 107 prefix which have prefix len of 8
There are 3 prefix which have prefix len of 9
There are 5 prefix which have prefix len of 10
There are 9 prefix which have prefix len of 11
There are 47 prefix which have prefix len of 12
There are 70 prefix which have prefix len of 13
There are 164 prefix which have prefix len of 14
There are 317 prefix which have prefix len of 15
There are 6117 prefix which have prefix len of 16
There are 1083 prefix which have prefix len of 17
There are 1769 prefix which have prefix len of 18
There are 4489 prefix which have prefix len of 19
There are 5553 prefix which have prefix len of 20
There are 4246 prefix which have prefix len of 21
There are 6090 prefix which have prefix len of 22
There are 7772 prefix which have prefix len of 23
There are 43679 prefix which have prefix len of 24
There are 383 prefix which have prefix len of 25
There are 387 prefix which have prefix len of 26
There are 439 prefix which have prefix len of 27
There are 338 prefix which have prefix len of 28
There are 989 prefix which have prefix len of 29
There are 454 prefix which have prefix len of 30
There are 1 prefix which have prefix len of 31
There are 113 prefix which have prefix len of 32
[ OK ] Reached target length_distribution.
'd' is 8
There are 4949 prefix in group 3355443200 (200.0.0.0/8)
```

84633
routing_table.txt Normal file

File diff suppressed because it is too large Load Diff

1
search.csv Normal file

File diff suppressed because one or more lines are too long

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
}

89088
trace_file.txt Normal file

File diff suppressed because it is too large Load Diff