before next stage
This commit is contained in:
commit
c6f08be676
|
@ -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
|
|
@ -0,0 +1,8 @@
|
|||
/cmake_install.cmake
|
||||
/build
|
||||
/.vscode
|
||||
/CMakeFiles
|
||||
/Makefile
|
||||
/CMakeCache.txt
|
||||
*.profdata
|
||||
*.profraw
|
|
@ -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
|
||||
)
|
|
@ -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)
|
File diff suppressed because it is too large
Load Diff
|
@ -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.
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
Binary file not shown.
|
@ -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);
|
|
@ -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);
|
|
@ -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);
|
|
@ -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);
|
|
@ -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;
|
||||
};
|
|
@ -0,0 +1,2 @@
|
|||
void input(struct State* state);
|
||||
void length_distribution(struct State* state);
|
|
@ -0,0 +1,3 @@
|
|||
#include "state.h"
|
||||
|
||||
void segment(struct State* state);
|
|
@ -0,0 +1,3 @@
|
|||
void prefix_insert(struct State* state);
|
||||
void prefix_delete(struct State* state);
|
||||
void search(struct State* state);
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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
|
||||
[34mWelcome to homework 11 (HW11)![0m
|
||||
Does it look very familiar?
|
||||
|
||||
[ [32mOK[0m ] Reached target [33minput[0m.
|
||||
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
|
||||
[ [32mOK[0m ] Reached target [33mlength_distribution[0m.
|
||||
'd' is 8
|
||||
There are 4949 prefix in group 3355443200 (200.0.0.0/8)
|
||||
```
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
// }
|
|
@ -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;
|
||||
// }
|
|
@ -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;
|
||||
// }
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
// }
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue