├── Lab1 ├── README.md └── src │ ├── An_example.png │ ├── ExampleInput.png │ ├── Input_file.png │ ├── Sudoku │ ├── Lab1.sh │ ├── Makefile │ ├── README │ ├── answer1 │ ├── answer1000 │ ├── answer10000 │ ├── answer_group │ ├── main.cc │ ├── mythreadpool.h │ ├── neighbor.cc │ ├── sudoku.h │ ├── sudoku_basic.cc │ ├── sudoku_dancing_links.cc │ ├── sudoku_min_arity.cc │ ├── sudoku_min_arity_cache.cc │ ├── taskqueue.h │ ├── test.cc │ ├── test1 │ ├── test1000 │ ├── test10000 │ ├── test_group │ ├── threadpool.cc │ └── threadpool.h │ ├── Sudoku_answer.png │ ├── Sudoku_puzzle.png │ ├── Wrong_Example.png │ ├── answer_group.png │ ├── test_group.png │ ├── where_ext4.png │ ├── 图2-1.png │ ├── 图2-2.png │ └── 图2-3.png ├── Lab2 ├── README.md └── src │ ├── get_404_curl.png │ ├── index.png │ ├── index_curl.png │ ├── not_implemented.png │ ├── not_implemented_curl.png │ ├── post_404_curl.png │ └── post_curl.png ├── Lab3 ├── README.md └── src │ ├── KVStoreOverview.jpg │ ├── KVStoreOverview.pptx │ ├── coordinator_sample.conf │ ├── participant_sample.conf │ └── two-phase-commit.png ├── Lab4 └── README.md └── README.md /Lab1/README.md: -------------------------------------------------------------------------------- 1 | # Lab 1: “Super-fast” Sudoku Solving 2 | 3 | Enter in the folder you have cloned from our lab git repo, and pull the latest commit. 4 | 5 | `git pull` 6 | 7 | You can find this lab1's instruction in `Lab1/README.md` 8 | 9 | All materials of lab1 are in folder `Lab1/` 10 | 11 | ## 1. Overview 12 | 13 | Implement a Sudoku solving program, using multiple threads or multiple processes, running on a single machine. Try to **utilize all your CPU cores** and make your program **run as fast as possible**! 14 | 15 | ### Goals 16 | 17 | * Practice basic parallel programming skills, such as using multiple threads/processes; 18 | * Get familiar with Unix OS environment development (eg., file I/O, get timestamp); 19 | * Get familiar with source code version control tools (git), and learn to collaborate with others using github; 20 | 21 | ## 2. Background 22 | 23 | ### 2.1 Introduction to Sudoku 24 | 25 | Sudoku (originally called Number Place) is a logic-based combinatorial number-placement puzzle. 26 | 27 | You are given a 9×9 board of 81 squares logically separated into 9 columsn, 9 rows, and 9 3×3 subsquares. The goal is, given a board with some initial numbers filled in (we call it a **Sudoku puzzle**), fill in the rest of the board so that every column, row, and subsquare have all the digits from 1 to 9 and each digit appears only once (we call it a **Sudoku solution**). 28 | 29 | 30 | An example Sudoku puzzle: 31 | 32 | Sudoku 33 | 34 | An example Sudoku solution to above puzzle: 35 | 36 | Sudoku 37 | 38 | ### 2.2 Some useful resources 39 | 40 | If you have no idea about what algorithms can be used to solve Sudoku puzzles, we suggest you read [this](https://rafal.io/posts/solving-sudoku-with-dancing-links.html). To simplify your work, we have provided a simple [implementation](src/Sudoku/) `(Lab1/src/Sudoku`) of 4 Sudoku solving algorithms (some are slow, some are fast), but without using multiple threads/processes. The two files *test1* and *test1000* contain many puzzles for you to test. 41 | 42 | Of course, you are always encouraged (not mandatory) to implement those algorithms by yourselves and even your own algorithms (if you have time). 43 | 44 | ## 3. Your Lab Task 45 | 46 | ### 3.1 Write a program 47 | 48 | Implement a program which satisfies the following requirements: 49 | 50 | #### 3.1.1 Program input and output 51 | 52 | ##### **3.1.1.1 Input** 53 | 54 | 1. Your program **must** have no arguments during start. Attention, your program must be called *sudoku_solve*, just typing `./sudoku_solve` and your program will run correctly. 55 | 2. But after start, your program should be able to read multiple strings from ***stdin***, where each string is separated by a line-break. Each string is a **name of a file**, which contains one or more Sudoku puzzles that your program is going to solve. 56 | 3. In the input file, **each line** is a Sudoku puzzle that needs to be solved. Each line contains 81 decimal digits. The 1st-9th digits are the 1st row of the 9×9 grid, and the 10th-18th digits are the 2nd row of the 9×9 grid, and so on. Digit 0 means this digit is unknown and your program needs to figure it out according to the Sudoku rules described above. 57 | 58 | **Example contents** 59 | 60 | Input file 61 | 62 | **Example input** 63 | 64 | ``` 65 | ./test1 66 | ./test2 67 | ./test3 68 | ``` 69 | 70 | ##### 3.1.1.2 Output 71 | 72 | For each test case, you just only output the Sudoku solutions. And don't forget, the output order should correspond with the input order of Sudoku puzzles. 73 | 74 | **Example output** 75 | 76 | ``` 77 | 312647985786953241945128367854379126273461859691285473437592618569814732128736594 78 | 693784512487512936125963874932651487568247391741398625319475268856129743274836159 79 | 869725413512934687374168529798246135231857946456319872683571294925483761147692358 80 | 693784512487512936125963874932651487568247391741398625319475268856129743274836159 81 | 364978512152436978879125634738651429691247385245389167923764851486512793517893246 82 | 378694512564218397291753684643125978712869453859437261435971826186542739927386145 83 | ``` 84 | 85 | **Output order requirement** 86 | 87 | In the example of input above, the order of filename entered is `./test1`, `./test2` and `./test3`. So, you should output the solutions of Sudoku puzzles in file `test1` firstly, then file `test2` and finally file `test3`. Needless to say, the solutions should be outputed in the same sequence as the puzzles are inputted in. 88 | 89 | In the example of output above, the 1st line is the solution of Sudoku puzzle in file `test1`. After that, the 2nd line and 3rd line are the solutions of 1st and 2nd Sudoku puzzles in file `test2`. Finally, the 4th line, 5th line and 6th line are the solutions of 1st, 2nd and 3rd Sudoku puzzles in file `test3`. 90 | 91 | #### 3.1.3 Implementation requirements 92 | 93 | ##### 3.1.3.1 Basic version 94 | 95 | Your program should be able to: 96 | 97 | 1. Accept **one** input file name, and the size of the input file is smaller than 100MB. 98 | 2. Successfully solve the puzzles in the input file, and output the results in the format described before. 99 | 3. Use multiple threads/processes to make use of most of your machine's CPU cores. 100 | 101 | \[Tips\]: 1) Use event queue to dispatch tasks and merge results to/from worker threads. 2) Dynamically detect how many CPU cores are there on your machine, in order to decide how many threads/processes your program uses. 3) Be careful about the contention among multiple threads/processes 102 | 103 | ##### 3.1.3.2 Advanced version 104 | 105 | Your program should be able to: 106 | 107 | 1. Complete all the requirements in the basic version. 108 | 2. Accept **any number of** input file names, and the size of input file can be **any large** (as long as it can be stored on your disk) 109 | 3. When the program is solving puzzles in the previously input file(s), the program can **meanwhile accept more input file names from *stdin***. 110 | 111 | \[Tips\]: 1) Use a dedicated thread to accept input; 2) To avoid consuming all the memory, read different parts of the file into memory and solve them one by one; 3) You are encouraged to try more optimizations such as cache coherency processing. 112 | 113 | ### 3.2. Test script 114 | 115 | You can test your program using the script (Lab1.sh) that comes with this Lab. 116 | 117 | ##### 3.2.1 Notes 118 | 119 | 1. You can use the script on most Linux environments 120 | 121 | 2. Requires support for the **screen** command 122 | 123 | ​ You can use "***which screen***" to see if the screen command is already installed, if not you can refer to the following command download: 124 | 125 | ```shell 126 | ubuntu: apt-get install screen 127 | 128 | centos: yum install screen 129 | ``` 130 | 131 | 3. The executable file can only be named **sudoku_solve** 132 | 133 | 4. sudoku_solve executable file, Lab1.sh script should be placed in the same directory 134 | 135 | 5. If your file system is not in **ext4** format, the performance test may not succeed and only the basic test can be performed. 136 | 137 | ​ You can see which path mounted ext4 disks in the following way: 138 | 139 | ```shell 140 | df -h --type=ext4 141 | ``` 142 | 143 | Sudoku 144 | 145 | 6. The script will generate a subfolder with Basic(Advanced)\_Result and Basic(Advanced)_Answer, Result is your output and Answer is the reference output. At each run, the script will delete the two files , so if you need this data, please copy it first before running the script. 146 | 147 | 7. The time taken for script presentation is relative, each time there will be a relatively fixed processing time. For example, your program used 1300ms to solve the sudoku problem, but the script preparation took 800ms. eventually, the script will show 2100ms. Also everyone's configuration and performance is different, resulting in different times, which means you only need to keep optimizing on your machine, not comparing it with others. Please be assured that the same environment will be used for the final scoring. 148 | 149 | 8. (**Very important**) If you want to get a high score (script test), it is better to flush the data in the buffer in time. 150 | 151 | ##### 3.2.2 Script Usage 152 | 153 | ```shell 154 | sudo ./Lab1.sh test_group answer_group 155 | ``` 156 | 157 | Parameter explanation: 158 | 159 | ​ The script takes two parameters 160 | 161 | ​ Para1(For example: test_group ) : A file that create by yourself. This file is placed in the path of the different test files. For example, if the test file group contains: . /test1 . /test1000 two input test files, the structure is as follows: 162 | 163 | Sudoku 164 | 165 | ​ Para2(For example: answer_group) : A file like parameter 1 but with the path to the answer to the test file. For example, if the test file group contains: . /test1 . /test1000 two input test files, the answer file group contains: . /answer1 . /answer1000 , and the structure is as follows: 166 | 167 | Sudoku 168 | 169 | You can create your own test files and put in the combinations you want. 170 | 171 | Note that this output below means that you are missing a line break at the end of your test file, which will not be recognized. Of course, the path of your answer file should be in the same order as the test path. 172 | 173 | Sudoku 174 | 175 | An example: 176 | 177 | Sudoku 178 | 179 | ## 4. Lab submission 180 | 181 | Please put all your code in folder `Lab1` and write a `Makefile` so that we **can compile your code in one single command** `make`. The compiled runnable executable binary should be named `sudoku_solve` and located in folder `Lab1`. If you do not know how to write `Makefile`, you can find a simple example in `Lab1/src/Sudoku`. Please carefully following above rules so that TAs can automatically test your code!!! 182 | 183 | Please submit your lab program and performance test report following the guidance in the [Overall Lab Instructions](../README.md) (`../README.md`) 184 | 185 | ## 5. Grading standards 186 | 187 | 1. You can get 38 points if you can: 1) finish all the requirements of the basic version, and 2) your performance test report has finished the two requirements described before. If you missed some parts, you will get part of the points depending how much you finished 188 | 2. You can get 40 points (full score) if you can: 1) finish all the requirements of the advanced version, and 2) your performance test report has finished the two requirements described before. If you missed some parts, you will get part of the points depending how much you finished. 189 | 190 | -------------------------------------------------------------------------------- /Lab1/src/An_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/An_example.png -------------------------------------------------------------------------------- /Lab1/src/ExampleInput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/ExampleInput.png -------------------------------------------------------------------------------- /Lab1/src/Input_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/Input_file.png -------------------------------------------------------------------------------- /Lab1/src/Sudoku/Lab1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #~/test_data/advanced_test (include test1 test1000) 3 | if [ $# != 2 ] ; then 4 | echo "参数数量不对" 5 | echo "参数1:包含测试文件组的文件 例如 \"test_group\" (其中可能包含 ./test1 ./test1000) " 6 | echo "参数2:包含测试文件组的文件 例如 \"answer_group\" (其中可能包含 ./answer1 ./answer1000) " 7 | echo "完整命令列如 : $0 test_group" 8 | exit 1; 9 | fi 10 | 11 | test_data_txt=$1 12 | answer_date_txt=$2 13 | GROUP_NAME="group1" 14 | Current_Folder=$(cd `dirname $0`; pwd) 15 | Record_Time="${test_data_txt}_Folder/Record_Time.csv" 16 | Error_Teams="${test_data_txt}_Folder/Error_Teams.csv" 17 | 18 | if [ -e ${test_data_txt}_Folder ];then 19 | echo "${test_data_txt}_Folder 无需创建,已存在" 20 | else 21 | mkdir ${test_data_txt}_Folder 22 | echo "创建${test_data_txt}_Folder" 23 | fi 24 | 25 | touch ${Record_Time} 26 | 27 | echo "Team_Name,Use_Time(ms),Creat_Time,Modify_Time" > ${Record_Time} 28 | 29 | #$1 team_name $2 Result_name $3 ${Answer_Line} $4 diff_line 30 | Cul_Run_Time(){ 31 | # stat $2 32 | 33 | INODE=$(ls -i $2 |awk '{print $1}') 34 | FILENAME=$2 35 | 36 | string=$(pwd) 37 | array=(${string//\// }) 38 | root_Directory=${array[0]}; 39 | 40 | DISK=$(df -h |grep ${root_Directory} |awk '{print $1}') 41 | 42 | # 文件系统非ext4则退出 43 | [[ "`df -T | grep ${DISK} |awk '{print $2}'`" != "ext4" ]] && { echo ${DISK} is not mount on type ext4! Only ext4 file system support!;exit 2; } 44 | 45 | Create_Time_t=$(sudo debugfs -R "stat <${INODE}>" ${DISK} | grep "crtime:" | awk '{printf $7}') 46 | 47 | Access_Time_t=$(stat $2 | grep "Access: 2" | awk '{printf $3}') 48 | Modify_Time_t=$(stat $2 | grep Modify | awk '{printf $3}') 49 | # echo "Access_Time_t:$Access_Time_t Modify_Time_t:$Modify_Time_t" 50 | echo "Create_Time_t:$Create_Time_t Modify_Time_t:$Modify_Time_t" 51 | # Access_Time=$(date -d ${Access_Time_t} +%s%N) 52 | Create_Time_t=$(date -d ${Create_Time_t} +%s%N) 53 | Modify_Time=$(date -d ${Modify_Time_t} +%s%N) 54 | # echo "$1 A is $Access_Time M is $Modify_Time" 55 | # Use_Time=`echo $Modify_Time $Access_Time | awk '{ print ($1 - $2) / 1000000}'` 56 | echo "$1 Cr is $Create_Time_t M is $Modify_Time" 57 | Use_Time=`echo $Modify_Time $Create_Time_t | awk '{ print ($1 - $2) / 1000000}'` 58 | # Check_Answer $1 $2 $3 59 | echo -e "\033[32m $1 Use_Time: $Use_Time ms \033[0m" 60 | 61 | Team_Answer=$(cat $2 | wc -l) 62 | if [[ ${Team_Answer} -ge $3 ]];then 63 | echo -e "\033[32m Up to standard Team_Answer:${Team_Answer} Answer_Line:$3 \033[0m" 64 | else 65 | echo -e "\033[31m Not up to standard Team_Answer:${Team_Answer} Answer_Line:$3 \033[0m" 66 | echo "$1 Not up to standard Team_Answer:${Team_Answer} Answer_Line:$3" >> ${Error_Teams} 67 | fi 68 | 69 | right_rate=$(echo "scale=2;1 - $4 / $3" | bc) 70 | # echo "$1,${right_rate},$Use_Time,${Team_Answer},$3,,$Access_Time_t,$Modify_Time_t" 71 | # echo "$1,${right_rate},$Use_Time,${Team_Answer},$3,,$Access_Time_t,$Modify_Time_t" >> ${Record_Time} 72 | } 73 | 74 | Basic_Test(){ 75 | # $1 team_name $2 test_data_file_name $3 answer_date_file_name 76 | test_data=$(cat $2) # ./test1 kml 77 | Answer_Line=0 78 | Exe_Prog="" 79 | cd ${Current_Folder} 80 | Result="${test_data_txt}_Folder/Basic_Result" 81 | Answer="${test_data_txt}_Folder/Basic_Answer" 82 | 83 | if [[ -e sudoku_solve ]];then 84 | echo "找到执行文件sudoku_solve" 85 | Exe_Prog='sudoku_solve' 86 | elif [[ -e sudoku ]];then 87 | echo "找到执行文件sudoku" 88 | Exe_Prog='sudoku' 89 | else 90 | echo "未找到命名为sudoku或sudoku_solve的执行文件" 91 | echo "进行编译" 92 | make 93 | if [[ -e sudoku_solve ]];then 94 | echo "找到执行文件sudoku_solve" 95 | Exe_Prog='sudoku_solve' 96 | elif [[ -e sudoku ]];then 97 | echo "找到执行文件sudoku" 98 | Exe_Prog='sudoku' 99 | else 100 | echo "编译后仍未找到相应执行文件" 101 | exit 1; 102 | fi 103 | fi 104 | 105 | if [[ -e ./${Answer} ]];then 106 | rm ./${Answer} 107 | touch ./${Answer} 108 | else 109 | touch ./${Answer} 110 | fi 111 | sudo chmod 777 ./${Answer} 112 | screen -S $1 -X quit 113 | screen -dmS $1 114 | 115 | if [[ -e ./${Result} ]];then 116 | rm ./${Result} 117 | touch ./${Result} 118 | else 119 | touch ./${Result} 120 | fi 121 | 122 | screen -S $1 -X stuff "stdbuf -oL ./${Exe_Prog} > ./${Result}^M" 123 | while read -r test_data 124 | do 125 | Answer_Line=`expr ${Answer_Line} + $(cat ${test_data} | wc -l)` 126 | screen -S $1 -X stuff "${test_data}^M" 127 | done < $2 128 | 129 | while read -r answer_data 130 | do 131 | cat ${Current_Folder}/${answer_data} >> ${Current_Folder}/${Answer} 132 | done < $3 133 | 134 | sleep 30 135 | screen -S $1 -X stuff "^C^M" 136 | screen -S $1 -X quit 137 | 138 | diff_line=$(diff -ab ./${Result} ./${Answer} | wc -l) 139 | echo -e "\033[32m 错误个数:$diff_line / ${Answer_Line} \033[0m" 140 | Cul_Run_Time $1 ${Current_Folder}/${Result} ${Answer_Line} ${diff_line} 141 | } 142 | 143 | Advanced_Test(){ 144 | # $1 team_name $2 test_data_file_name 145 | test_data=$(cat $2) # ./test10000 146 | Answer_Line=0 147 | Exe_Prog="" 148 | cd ${Current_Folder} 149 | Result="${test_data_txt}_Folder/Advanced_Result" 150 | Answer="${test_data_txt}_Folder/Advanced_Answer" 151 | 152 | if [[ -e sudoku_solve ]];then 153 | echo "找到执行文件sudoku_solve" 154 | Exe_Prog='sudoku_solve' 155 | elif [[ -e sudoku ]];then 156 | echo "找到执行文件sudoku" 157 | Exe_Prog='sudoku' 158 | else 159 | echo "未找到命名为sudoku或sudoku_solve的执行文件" 160 | echo "进行编译" 161 | make 162 | if [[ -e sudoku_solve ]];then 163 | echo "找到执行文件sudoku_solve" 164 | Exe_Prog='sudoku_solve' 165 | elif [[ -e sudoku ]];then 166 | echo "找到执行文件sudoku" 167 | Exe_Prog='sudoku' 168 | else 169 | echo "编译后仍未找到相应执行文件" 170 | exit 1; 171 | fi 172 | fi 173 | 174 | if [[ -e ./${Answer} ]];then 175 | rm ./${Answer} 176 | touch ./${Answer} 177 | else 178 | touch ./${Answer} 179 | fi 180 | sudo chmod 777 ./${Answer} 181 | screen -S $1 -X quit 182 | screen -dmS $1 183 | 184 | if [[ -e ./${Result} ]];then 185 | rm ./${Result} 186 | touch ./${Result} 187 | else 188 | touch ./${Result} 189 | fi 190 | 191 | screen -S $1 -X stuff "stdbuf -oL ./${Exe_Prog} > ./${Result}^M" 192 | while read -r test_data 193 | do 194 | Answer_Line=`expr ${Answer_Line} + $(cat ${test_data} | wc -l)` 195 | screen -S $1 -X stuff "${test_data}^M" 196 | done < $2 197 | 198 | while read -r answer_data 199 | do 200 | cat ${Current_Folder}/${answer_data} >> ${Current_Folder}/${Answer} 201 | done < $3 202 | 203 | sleep 30 204 | screen -S $1 -X stuff "^C^M" 205 | screen -S $1 -X quit 206 | 207 | diff_line=$(diff -ab ./${Result} ./${Answer} | wc -l) 208 | echo -e "\033[32m 错误个数:$diff_line / ${Answer_Line} \033[0m" 209 | Cul_Run_Time $1 ${Current_Folder}/${Result} ${Answer_Line} ${diff_line} 210 | } 211 | 212 | 213 | if [ -e ${test_data_txt} ];then 214 | Running_Version=$(cat ${test_data_txt} | wc -l) 215 | echo "测试样例:$Running_Version 个" 216 | cat ${test_data_txt} 217 | if [[ $Running_Version == 1 ]];then 218 | echo -e "\033[32m --------------${GROUP_NAME} is running Basic_Test-------------- \033[0m" 219 | Basic_Test ${GROUP_NAME} ${test_data_txt} ${answer_date_txt} 220 | elif [[ $Running_Version == 0 ]];then 221 | echo "请检查输入格式,确保文件末尾有一个换行,参照实验指导书" 222 | else 223 | echo -e "\033[32m --------------${GROUP_NAME} is running Advanced_Test--------------\033[0m" 224 | Advanced_Test ${GROUP_NAME} ${test_data_txt} ${answer_date_txt} 225 | fi 226 | else 227 | echo "文件$1不存在" 228 | exit 1; 229 | fi 230 | 231 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/Makefile: -------------------------------------------------------------------------------- 1 | CXXFLAGS+=-O2 -ggdb -DDEBUG 2 | CXXFLAGS+=-Wall -Wextra 3 | 4 | all: sudoku 5 | 6 | sudoku: main.cc neighbor.cc sudoku_basic.cc sudoku_min_arity.cc sudoku_min_arity_cache.cc sudoku_dancing_links.cc 7 | g++ -O2 -o $@ $^ 8 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/README: -------------------------------------------------------------------------------- 1 | A backtracking sudoku solver, four algorithms are shown. 2 | 3 | test cases are from http://people.csse.uwa.edu.au/gordon/sudokumin.php 4 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/answer1: -------------------------------------------------------------------------------- 1 | 693784512487512936125963874932651487568247391741398625319475268856129743274836159 2 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/answer_group: -------------------------------------------------------------------------------- 1 | ./answer1 2 | ./answer1000 3 | ./answer1000 4 | ./answer10000 5 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "sudoku.h" 8 | 9 | int64_t now() 10 | { 11 | struct timeval tv; 12 | gettimeofday(&tv, NULL); 13 | return tv.tv_sec * 1000000 + tv.tv_usec; 14 | } 15 | 16 | int main(int argc, char* argv[]) 17 | { 18 | init_neighbors(); 19 | 20 | FILE* fp = fopen(argv[1], "r"); 21 | char puzzle[128]; 22 | int total_solved = 0; 23 | int total = 0; 24 | bool (*solve)(int) = solve_sudoku_basic; 25 | if (argv[2] != NULL) 26 | if (argv[2][0] == 'a') 27 | solve = solve_sudoku_min_arity; 28 | else if (argv[2][0] == 'c') 29 | solve = solve_sudoku_min_arity_cache; 30 | else if (argv[2][0] == 'd') 31 | solve = solve_sudoku_dancing_links; 32 | int64_t start = now(); 33 | while (fgets(puzzle, sizeof puzzle, fp) != NULL) { 34 | if (strlen(puzzle) >= N) { 35 | ++total; 36 | input(puzzle); 37 | init_cache(); 38 | //if (solve_sudoku_min_arity_cache(0)) { 39 | //if (solve_sudoku_min_arity(0)) 40 | //if (solve_sudoku_basic(0)) { 41 | if (solve(0)) { 42 | ++total_solved; 43 | if (!solved()) 44 | assert(0); 45 | } 46 | else { 47 | printf("No: %s", puzzle); 48 | } 49 | } 50 | } 51 | int64_t end = now(); 52 | double sec = (end-start)/1000000.0; 53 | printf("%f sec %f ms each %d\n", sec, 1000*sec/total, total_solved); 54 | 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/mythreadpool.h: -------------------------------------------------------------------------------- 1 | #ifndef MYTHREADPOOL_H 2 | #define MYTHREADPOOL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "taskqueue.h" 15 | 16 | // 定义任务结构体 17 | using namespace std; 18 | namespace mythreadpool{ 19 | class ThreadPool 20 | { 21 | public: 22 | ThreadPool( int maxnum){ 23 | // 实例化任务队列 24 | m_taskQ = new taskqueue::TaskQueue; 25 | do { 26 | // 初始化线程池 27 | 28 | m_maxNum = maxnum; 29 | m_busyNum = 0; 30 | m_aliveNum = 0; 31 | 32 | // 根据线程的最大上限给线程数组分配内存 33 | m_threadIDs = new pthread_t[maxnum]; 34 | if (m_threadIDs == nullptr) 35 | { 36 | cout << "malloc thread_t[] 失败...." << endl;; 37 | break; 38 | } 39 | // 初始化 40 | memset(m_threadIDs, 0, sizeof(pthread_t) * maxNum); 41 | // 初始化互斥锁,条件变量 42 | if (pthread_mutex_init(&m_lock, NULL) != 0 || 43 | pthread_cond_init(&m_notEmpty, NULL) != 0) 44 | { 45 | cout << "init mutex or condition fail..." << endl; 46 | break; 47 | } 48 | 49 | /////////////////// 创建线程 ////////////////// 50 | // 根据最小线程个数, 创建线程 51 | for (int i = 0; i < minNum; ++i) 52 | { 53 | pthread_create(&m_threadIDs[i], NULL, worker, this); 54 | cout << "创建子线程, ID: " << to_string(m_threadIDs[i]) << endl; 55 | } 56 | // 创建管理者线程, 1个 57 | pthread_create(&m_managerID, NULL, manager, this); 58 | } while (0); 59 | } 60 | ~ThreadPool(); 61 | 62 | // 添加任务 63 | void addTask(taskqueue::Task task){ 64 | if(m_shutdown) return; 65 | m_taskQ->addTask(task); 66 | pthread_cond_signal(&m_notEmpty); 67 | 68 | } 69 | // 获取忙线程的个数 70 | int getBusyNumber(); 71 | // 获取活着的线程个数 72 | int getAliveNumber(); 73 | 74 | private: 75 | // 工作的线程的任务函数 76 | static void* worker(void* arg){ 77 | ThreadPool* pool = (ThreadPool*)arg; 78 | while (true) 79 | { 80 | pthread_mutex_lock(&pool->m_lock); 81 | //任务为空且还在运行,阻塞线程 82 | while (pool->m_taskQ->taskNumber()==0&& !pool->m_shutdown) 83 | { 84 | pthread_cond_wait(&pool->m_notEmpty,&pool->m_lock); 85 | if(pool->m_exitNum>0){//有线程退出 86 | pool->m_exitNum--; 87 | pthread_mutex_unlock(&pool->m_lock); 88 | pool->threadExit();//单个线程退出 89 | } 90 | } 91 | 92 | if(pool->m_shutdown){ 93 | pthread_mutex_unlock(&pool->m_lock); 94 | pool->threadExit(); 95 | } 96 | taskqueue::Task task=pool->m_taskQ->takeTask(); 97 | pool->m_busyNum++; 98 | pthread_mutex_unlock(&pool->m_lock); 99 | printf("thread %ld start working\n",pthread_self()); 100 | 101 | 102 | task.fun(task.arg); 103 | delete task.arg; 104 | task.arg=nullptr; 105 | 106 | printf("thread %ld end working\n",pthread_self()); 107 | 108 | pthread_mutex_lock(&pool->m_lock); 109 | pool->m_busyNum--; 110 | pthread_mutex_unlock(&pool->m_lock); 111 | 112 | } 113 | return; 114 | 115 | } 116 | 117 | // 管理者线程的任务函数 118 | static void* manager(void* arg); 119 | void threadExit(){ 120 | pthread_t tid = pthread_self(); 121 | for(int i=0;i 2 | #include 3 | #include 4 | 5 | #include "sudoku.h" 6 | 7 | #include 8 | 9 | int neighbors[N][NEIGHBOR]; 10 | 11 | static void mark_adjacent(bool adjacent[ROW][COL], int row, int col) 12 | { 13 | for (int i = 0; i < NUM; ++i) { 14 | adjacent[row][i] = true; 15 | adjacent[i][col] = true; 16 | } 17 | int top = (row/3)*3; 18 | int left = (col/3)*3; 19 | adjacent[top][left] = true; 20 | adjacent[top][left+1] = true; 21 | adjacent[top][left+2] = true; 22 | adjacent[top+1][left] = true; 23 | adjacent[top+1][left+1] = true; 24 | adjacent[top+1][left+2] = true; 25 | adjacent[top+2][left] = true; 26 | adjacent[top+2][left+1] = true; 27 | adjacent[top+2][left+2] = true; 28 | } 29 | 30 | static void collect_neighbors(const bool adjacent[ROW][COL], int row, int col, int myneighbors[NEIGHBOR]) 31 | { 32 | int n = 0; 33 | for (int y = 0; y < ROW; ++y) { 34 | for (int x = 0; x < COL; ++x) { 35 | if (adjacent[y][x] && !(y == row && x == col)) { 36 | assert(n < NEIGHBOR); 37 | myneighbors[n++] = y*COL + x; 38 | } 39 | } 40 | } 41 | assert(n == NEIGHBOR); 42 | } 43 | 44 | static void print_neighbors(const bool adjacent[ROW][COL], int row, int col, int myneighbors[NEIGHBOR]) 45 | { 46 | for (int y = 0; y < ROW; ++y) { 47 | for (int x = 0; x < COL; ++x) { 48 | if (y == row && x == col) 49 | putchar('X'); 50 | else 51 | putchar(adjacent[y][x] ? 'o' : '.'); 52 | } 53 | printf("\n"); 54 | } 55 | for (int i = 0; i < NEIGHBOR; ++i) { 56 | printf("%2d, ", myneighbors[i]); 57 | } 58 | puts("\n"); 59 | } 60 | 61 | /*public*/ void init_neighbors() 62 | { 63 | for (int row = 0; row < ROW; ++row) { 64 | for (int col = 0; col < COL; ++col) { 65 | bool adjacent[ROW][COL]; 66 | bzero(adjacent, sizeof adjacent); 67 | mark_adjacent(adjacent, row, col); 68 | 69 | int me = row*COL + col; 70 | collect_neighbors(adjacent, row, col, neighbors[me]); 71 | 72 | if (DEBUG_MODE) 73 | print_neighbors(adjacent, row, col, neighbors[me]); 74 | } 75 | } 76 | } 77 | 78 | bool solved() 79 | { 80 | for (int row = 0; row < ROW; ++row) { 81 | // check row 82 | int occurs[10] = { 0 }; 83 | for (int col = 0; col < COL; ++col) { 84 | int val = chess[row][col]; 85 | assert(1 <= val && val <= NUM); 86 | ++occurs[val]; 87 | } 88 | 89 | if (std::count(occurs, occurs+10, 1) != NUM) 90 | return false; 91 | } 92 | 93 | for (int col = 0; col < COL; ++col) { 94 | int occurs[10] = { 0 }; 95 | for (int row = 0; row < ROW; ++row) { 96 | int val = chess[row][col]; 97 | // assert(1 <= val && val <= NUM); 98 | ++occurs[val]; 99 | } 100 | 101 | if (std::count(occurs, occurs+10, 1) != NUM) 102 | return false; 103 | } 104 | 105 | for (int row = 0; row < ROW; row += 3) { 106 | for (int col = 0; col < COL; col += 3) { 107 | int occurs[10] = { 0 }; 108 | ++occurs[chess[row ][col]]; 109 | ++occurs[chess[row ][col+1]]; 110 | ++occurs[chess[row ][col+2]]; 111 | ++occurs[chess[row+1][col]]; 112 | ++occurs[chess[row+1][col+1]]; 113 | ++occurs[chess[row+1][col+2]]; 114 | ++occurs[chess[row+2][col]]; 115 | ++occurs[chess[row+2][col+1]]; 116 | ++occurs[chess[row+2][col+2]]; 117 | 118 | if (std::count(occurs, occurs+10, 1) != NUM) 119 | return false; 120 | } 121 | } 122 | return true; 123 | } 124 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/sudoku.h: -------------------------------------------------------------------------------- 1 | #ifndef SUDOKU_H 2 | #define SUDOKU_H 3 | 4 | const bool DEBUG_MODE = false; 5 | enum { ROW=9, COL=9, N = 81, NEIGHBOR = 20 }; 6 | const int NUM = 9; 7 | 8 | extern int neighbors[N][NEIGHBOR]; 9 | extern int board[N]; 10 | extern int spaces[N]; 11 | extern int nspaces; 12 | extern int (*chess)[COL]; 13 | 14 | void init_neighbors(); 15 | void input(const char in[N]); 16 | void init_cache(); 17 | 18 | bool available(int guess, int cell); 19 | 20 | bool solve_sudoku_basic(int which_space); 21 | bool solve_sudoku_min_arity(int which_space); 22 | bool solve_sudoku_min_arity_cache(int which_space); 23 | bool solve_sudoku_dancing_links(int unused); 24 | bool solved(); 25 | #endif 26 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/sudoku_basic.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include "sudoku.h" 7 | 8 | int board[N]; 9 | int spaces[N]; 10 | int nspaces; 11 | int (*chess)[COL] = (int (*)[COL])board; 12 | 13 | static void find_spaces() 14 | { 15 | nspaces = 0; 16 | for (int cell = 0; cell < N; ++cell) { 17 | if (board[cell] == 0) 18 | spaces[nspaces++] = cell; 19 | } 20 | } 21 | 22 | void input(const char in[N]) 23 | { 24 | for (int cell = 0; cell < N; ++cell) { 25 | board[cell] = in[cell] - '0'; 26 | assert(0 <= board[cell] && board[cell] <= NUM); 27 | } 28 | find_spaces(); 29 | } 30 | 31 | bool available(int guess, int cell) 32 | { 33 | for (int i = 0; i < NEIGHBOR; ++i) { 34 | int neighbor = neighbors[cell][i]; 35 | if (board[neighbor] == guess) { 36 | return false; 37 | } 38 | } 39 | return true; 40 | } 41 | 42 | bool solve_sudoku_basic(int which_space) 43 | { 44 | if (which_space >= nspaces) { 45 | return true; 46 | } 47 | 48 | // find_min_arity(which_space); 49 | int cell = spaces[which_space]; 50 | 51 | for (int guess = 1; guess <= NUM; ++guess) { 52 | if (available(guess, cell)) { 53 | // hold 54 | assert(board[cell] == 0); 55 | board[cell] = guess; 56 | 57 | // try 58 | if (solve_sudoku_basic(which_space+1)) { 59 | return true; 60 | } 61 | 62 | // unhold 63 | assert(board[cell] == guess); 64 | board[cell] = 0; 65 | } 66 | } 67 | return false; 68 | } 69 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/sudoku_dancing_links.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "sudoku.h" 7 | using namespace std; 8 | 9 | struct Node; 10 | typedef Node Column; 11 | struct Node 12 | { 13 | Node* left; 14 | Node* right; 15 | Node* up; 16 | Node* down; 17 | Column* col; 18 | int name; 19 | int size; 20 | }; 21 | 22 | const int kMaxNodes = 1 + 81*4 + 9*9*9*4; 23 | const int kMaxColumns = 400; 24 | const int kRow = 100, kCol = 200, kBox = 300; 25 | 26 | 27 | struct Dance 28 | { 29 | Column* root_; 30 | int* inout_; 31 | Column* columns_[400]; 32 | vector stack_; 33 | Node nodes_[kMaxNodes]; 34 | int cur_node_; 35 | 36 | Column* new_column(int n = 0) 37 | { 38 | assert(cur_node_ < kMaxNodes); 39 | Column* c = &nodes_[cur_node_++]; 40 | memset(c, 0, sizeof(Column)); 41 | c->left = c; 42 | c->right = c; 43 | c->up = c; 44 | c->down = c; 45 | c->col = c; 46 | c->name = n; 47 | return c; 48 | } 49 | 50 | void append_column(int n) 51 | { 52 | assert(columns_[n] == NULL); 53 | 54 | Column* c = new_column(n); 55 | put_left(root_, c); 56 | columns_[n] = c; 57 | } 58 | 59 | Node* new_row(int col) 60 | { 61 | assert(columns_[col] != NULL); 62 | assert(cur_node_ < kMaxNodes); 63 | 64 | Node* r = &nodes_[cur_node_++]; 65 | 66 | //Node* r = new Node; 67 | memset(r, 0, sizeof(Node)); 68 | r->left = r; 69 | r->right = r; 70 | r->up = r; 71 | r->down = r; 72 | r->name = col; 73 | r->col = columns_[col]; 74 | put_up(r->col, r); 75 | return r; 76 | } 77 | 78 | int get_row_col(int row, int val) 79 | { 80 | return kRow+row*10+val; 81 | } 82 | 83 | int get_col_col(int col, int val) 84 | { 85 | return kCol+col*10+val; 86 | } 87 | 88 | int get_box_col(int box, int val) 89 | { 90 | return kBox+box*10+val; 91 | } 92 | 93 | Dance(int inout[81]) : inout_(inout), cur_node_(0) 94 | { 95 | stack_.reserve(100); 96 | 97 | root_ = new_column(); 98 | root_->left = root_->right = root_; 99 | memset(columns_, 0, sizeof(columns_)); 100 | 101 | bool rows[N][10] = {false}; 102 | bool cols[N][10] = {false}; 103 | bool boxes[N][10] = {false}; 104 | 105 | for (int i = 0; i < N; ++i) { 106 | int row = i / 9; 107 | int col = i % 9; 108 | int box = row/3*3 + col/3; 109 | int val = inout[i]; 110 | rows[row][val] = true; 111 | cols[col][val] = true; 112 | boxes[box][val] = true; 113 | } 114 | 115 | for (int i = 0; i < N; ++i) { 116 | if (inout[i] == 0) { 117 | append_column(i); 118 | } 119 | } 120 | 121 | for (int i = 0; i < 9; ++i) { 122 | for (int v = 1; v < 10; ++v) { 123 | if (!rows[i][v]) 124 | append_column(get_row_col(i, v)); 125 | if (!cols[i][v]) 126 | append_column(get_col_col(i, v)); 127 | if (!boxes[i][v]) 128 | append_column(get_box_col(i, v)); 129 | } 130 | } 131 | 132 | for (int i = 0; i < N; ++i) { 133 | if (inout[i] == 0) { 134 | int row = i / 9; 135 | int col = i % 9; 136 | int box = row/3*3 + col/3; 137 | //int val = inout[i]; 138 | for (int v = 1; v < 10; ++v) { 139 | if (!(rows[row][v] || cols[col][v] || boxes[box][v])) { 140 | Node* n0 = new_row(i); 141 | Node* nr = new_row(get_row_col(row, v)); 142 | Node* nc = new_row(get_col_col(col, v)); 143 | Node* nb = new_row(get_box_col(box, v)); 144 | put_left(n0, nr); 145 | put_left(n0, nc); 146 | put_left(n0, nb); 147 | } 148 | } 149 | } 150 | } 151 | } 152 | 153 | Column* get_min_column() 154 | { 155 | Column* c = root_->right; 156 | int min_size = c->size; 157 | if (min_size > 1) { 158 | for (Column* cc = c->right; cc != root_; cc = cc->right) { 159 | if (min_size > cc->size) { 160 | c = cc; 161 | min_size = cc->size; 162 | if (min_size <= 1) 163 | break; 164 | } 165 | } 166 | } 167 | return c; 168 | } 169 | 170 | void cover(Column* c) 171 | { 172 | c->right->left = c->left; 173 | c->left->right = c->right; 174 | for (Node* row = c->down; row != c; row = row->down) { 175 | for (Node* j = row->right; j != row; j = j->right) { 176 | j->down->up = j->up; 177 | j->up->down = j->down; 178 | j->col->size--; 179 | } 180 | } 181 | } 182 | 183 | void uncover(Column* c) 184 | { 185 | for (Node* row = c->up; row != c; row = row->up) { 186 | for (Node* j = row->left; j != row; j = j->left) { 187 | j->col->size++; 188 | j->down->up = j; 189 | j->up->down = j; 190 | } 191 | } 192 | c->right->left = c; 193 | c->left->right = c; 194 | } 195 | 196 | bool solve() 197 | { 198 | if (root_->left == root_) { 199 | for (size_t i = 0; i < stack_.size(); ++i) { 200 | Node* n = stack_[i]; 201 | int cell = -1; 202 | int val = -1; 203 | while (cell == -1 || val == -1) { 204 | if (n->name < 100) 205 | cell = n->name; 206 | else 207 | val = n->name % 10; 208 | n = n->right; 209 | } 210 | 211 | //assert(cell != -1 && val != -1); 212 | inout_[cell] = val; 213 | } 214 | return true; 215 | } 216 | 217 | Column* const col = get_min_column(); 218 | cover(col); 219 | for (Node* row = col->down; row != col; row = row->down) { 220 | stack_.push_back(row); 221 | for (Node* j = row->right; j != row; j = j->right) { 222 | cover(j->col); 223 | } 224 | if (solve()) { 225 | return true; 226 | } 227 | stack_.pop_back(); 228 | for (Node* j = row->left; j != row; j = j->left) { 229 | uncover(j->col); 230 | } 231 | } 232 | uncover(col); 233 | return false; 234 | } 235 | 236 | void put_left(Column* old, Column* nnew) 237 | { 238 | nnew->left = old->left; 239 | nnew->right = old; 240 | old->left->right = nnew; 241 | old->left = nnew; 242 | } 243 | 244 | void put_up(Column* old, Node* nnew) 245 | { 246 | nnew->up = old->up; 247 | nnew->down = old; 248 | old->up->down = nnew; 249 | old->up = nnew; 250 | old->size++; 251 | nnew->col = old; 252 | } 253 | }; 254 | 255 | bool solve_sudoku_dancing_links(int unused) 256 | { 257 | Dance d(board); 258 | return d.solve(); 259 | } 260 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/sudoku_min_arity.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "sudoku.h" 6 | 7 | static int arity(int cell) 8 | { 9 | bool occupied[10] = {false}; 10 | for (int i = 0; i < NEIGHBOR; ++i) { 11 | int neighbor = neighbors[cell][i]; 12 | occupied[board[neighbor]] = true; 13 | } 14 | return std::count(occupied+1, occupied+10, false); 15 | } 16 | 17 | static void find_min_arity(int space) 18 | { 19 | int cell = spaces[space]; 20 | int min_space = space; 21 | int min_arity = arity(cell); 22 | 23 | for (int sp = space+1; sp < nspaces && min_arity > 1; ++sp) { 24 | int cur_arity = arity(spaces[sp]); 25 | if (cur_arity < min_arity) { 26 | min_arity = cur_arity; 27 | min_space = sp; 28 | } 29 | } 30 | 31 | if (space != min_space) { 32 | std::swap(spaces[min_space], spaces[space]); 33 | } 34 | } 35 | 36 | bool solve_sudoku_min_arity(int which_space) 37 | { 38 | if (which_space >= nspaces) { 39 | return true; 40 | } 41 | 42 | find_min_arity(which_space); 43 | int cell = spaces[which_space]; 44 | 45 | for (int guess = 1; guess <= NUM; ++guess) { 46 | if (available(guess, cell)) { 47 | // hold 48 | assert(board[cell] == 0); 49 | board[cell] = guess; 50 | 51 | // try 52 | if (solve_sudoku_min_arity(which_space+1)) { 53 | return true; 54 | } 55 | 56 | // unhold 57 | assert(board[cell] == guess); 58 | board[cell] = 0; 59 | } 60 | } 61 | return false; 62 | } 63 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/sudoku_min_arity_cache.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include "sudoku.h" 7 | 8 | static bool occupied[N][NUM+1]; 9 | static int arity[N]; 10 | 11 | static void find_min_arity(int space) 12 | { 13 | int cell = spaces[space]; 14 | int min_space = space; 15 | int min_arity = arity[cell]; 16 | 17 | for (int sp = space+1; sp < nspaces && min_arity > 1; ++sp) { 18 | int cur_arity = arity[spaces[sp]]; 19 | if (cur_arity < min_arity) { 20 | min_arity = cur_arity; 21 | min_space = sp; 22 | } 23 | } 24 | 25 | if (space != min_space) { 26 | std::swap(spaces[min_space], spaces[space]); 27 | } 28 | } 29 | 30 | void init_cache() 31 | { 32 | bzero(occupied, sizeof(occupied)); 33 | std::fill(arity, arity + N, NUM); 34 | for (int cell = 0; cell < N; ++cell) { 35 | occupied[cell][0] = true; 36 | int val = board[cell]; 37 | if (val > 0) { 38 | occupied[cell][val] = true; 39 | for (int n = 0; n < NEIGHBOR; ++n) { 40 | int neighbor = neighbors[cell][n]; 41 | if (!occupied[neighbor][val]) { 42 | occupied[neighbor][val] = true; 43 | --arity[neighbor]; 44 | } 45 | } 46 | } 47 | } 48 | } 49 | 50 | bool solve_sudoku_min_arity_cache(int which_space) 51 | { 52 | if (which_space >= nspaces) { 53 | return true; 54 | } 55 | 56 | find_min_arity(which_space); 57 | int cell = spaces[which_space]; 58 | 59 | for (int guess = 1; guess <= NUM; ++guess) { 60 | if (!occupied[cell][guess]) { 61 | // hold 62 | assert(board[cell] == 0); 63 | board[cell] = guess; 64 | occupied[cell][guess] = true; 65 | 66 | // remember changes 67 | int modified[NEIGHBOR]; 68 | int nmodified = 0; 69 | for (int n = 0; n < NEIGHBOR; ++n) { 70 | int neighbor = neighbors[cell][n]; 71 | if (!occupied[neighbor][guess]) { 72 | occupied[neighbor][guess] = true; 73 | --arity[neighbor]; 74 | modified[nmodified++] = neighbor; 75 | } 76 | } 77 | 78 | // try 79 | if (solve_sudoku_min_arity_cache(which_space+1)) { 80 | return true; 81 | } 82 | 83 | // unhold 84 | occupied[cell][guess] = false; 85 | assert(board[cell] == guess); 86 | board[cell] = 0; 87 | 88 | // undo changes 89 | for (int i = 0; i < nmodified; ++i) { 90 | int neighbor = modified[i]; 91 | assert(occupied[neighbor][guess]); 92 | occupied[neighbor][guess] = false; 93 | ++arity[neighbor]; 94 | } 95 | } 96 | } 97 | return false; 98 | } 99 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/taskqueue.h: -------------------------------------------------------------------------------- 1 | #ifndef TASKQUEUE_H 2 | #define TASKQUEUE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | // 定义任务结构体 16 | namespace taskqueue{ 17 | struct Task 18 | { 19 | void*(*fun)(void*) ;//函数指针 20 | void* arg;//函数参数 21 | Task() 22 | { 23 | fun = nullptr; 24 | arg = nullptr; 25 | } 26 | Task(void*(*f)(void*) , void* arg) 27 | { 28 | fun = f; 29 | this->arg = arg; 30 | } 31 | 32 | }; 33 | 34 | // 任务队列 35 | class TaskQueue 36 | { 37 | public: 38 | TaskQueue() 39 | { 40 | pthread_mutex_init(&m_mutex, NULL); 41 | } 42 | 43 | ~TaskQueue() 44 | { 45 | pthread_mutex_destroy(&m_mutex); 46 | } 47 | 48 | // 添加任务 49 | void addTask(Task& task) 50 | { 51 | pthread_mutex_lock(&m_mutex); 52 | myqueue.push_back(task); 53 | pthread_mutex_unlock(&m_mutex); 54 | } 55 | 56 | void addTask(void*(*f)(void*) , void* arg); 57 | void addTask(void*(*f)(void*), void* arg) 58 | { 59 | pthread_mutex_lock(&m_mutex); 60 | Task task; 61 | task.fun = f; 62 | task.arg = arg; 63 | myqueue.push_back(task); 64 | pthread_mutex_unlock(&m_mutex); 65 | } 66 | 67 | // 取出一个任务 68 | Task takeTask() 69 | { 70 | Task t; 71 | pthread_mutex_lock(&m_mutex); 72 | if (myqueue.size() > 0) 73 | { 74 | t = myqueue.front(); 75 | myqueue.pop_front(); 76 | } 77 | pthread_mutex_unlock(&m_mutex); 78 | return t; 79 | } 80 | 81 | // 获取当前队列中任务个数 82 | inline int taskNumber() 83 | { 84 | return myqueue.size(); 85 | } 86 | 87 | private: 88 | pthread_mutex_t m_mutex; // 互斥锁 89 | std::deque myqueue; // 任务队列 90 | }; 91 | } 92 | #endif -------------------------------------------------------------------------------- /Lab1/src/Sudoku/test.cc: -------------------------------------------------------------------------------- 1 | // main.c 2 | #include 3 | 4 | #include "threadpool.h" 5 | #include 6 | #include 7 | #include 8 | using namespace mythreadpool; 9 | void printString(const std::string &str) { 10 | std::cout << str << std::endl; 11 | usleep(100 * 100); 12 | } 13 | 14 | void test(int maxSize) { 15 | ThreadPool pool("pool"); 16 | pool.setqSize(maxSize); 17 | pool.start(5); 18 | for (int i = 0; i < 100; ++i) { 19 | std::string buf = "task" + std::to_string(i); 20 | pool.run(std::bind(printString, buf)); 21 | } 22 | pool.stop(); 23 | std::cout << "Done" << std::endl; 24 | } 25 | 26 | int main() { 27 | test(10); 28 | std::cout << "Hello, World!" << std::endl; 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/test1: -------------------------------------------------------------------------------- 1 | 000000010400000000020000000000050407008000300001090000300400200050100000000806000 2 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/test1000: -------------------------------------------------------------------------------- 1 | 000000010400000000020000000000050407008000300001090000300400200050100000000806000 2 | 000000010400000000020000000000050604008000300001090000300400200050100000000807000 3 | 000000012000035000000600070700000300000400800100000000000120000080000040050000600 4 | 000000012003600000000007000410020000000500300700000600280000040000300500000000000 5 | 000000012008030000000000040120500000000004700060000000507000300000620000000100000 6 | 000000012040050000000009000070600400000100000000000050000087500601000300200000000 7 | 000000012050400000000000030700600400001000000000080000920000800000510700000003000 8 | 000000012300000060000040000900000500000001070020000000000350400001400800060000000 9 | 000000012400090000000000050070200000600000400000108000018000000000030700502000000 10 | 000000012500008000000700000600120000700000450000030000030000800000500700020000000 11 | 000000012700060000000000050080200000600000400000109000019000000000030800502000000 12 | 000000012800040000000000060090200000700000400000501000015000000000030900602000000 13 | 000000012980000000000600000100700080402000000000300600070000300050040000000010000 14 | 000000013000030080070000000000206000030000900000010000600500204000400700100000000 15 | 000000013000200000000000080000760200008000400010000000200000750600340000000008000 16 | 000000013000500070000802000000400900107000000000000200890000050040000600000010000 17 | 000000013000700060000508000000400800106000000000000200740000050020000400000010000 18 | 000000013000700060000509000000400900106000000000000200740000050080000400000010000 19 | 000000013000800070000502000000400900107000000000000200890000050040000600000010000 20 | 000000013020500000000000000103000070000802000004000000000340500670000200000010000 21 | 000000013040000080200060000609000400000800000000300000030100500000040706000000000 22 | 000000013040000080200060000906000400000800000000300000030100500000040706000000000 23 | 000000013040000090200070000607000400000300000000900000030100500000060807000000000 24 | 000000013040000090200070000706000400000300000000900000030100500000060807000000000 25 | 000000013200800000300000070000200600001000000040000000000401500680000200000070000 26 | 000000013400200000600000000000460500010000007200500000000031000000000420080000000 27 | 000000013400800000200000070000400900001000000060000000000501600380000200000070000 28 | 000000014000000203800050000000207000031000000000000650600000700000140000000300000 29 | 000000014000020000500000000010804000700000500000100000000050730004200000030000600 30 | 000000014000708000000000000104005000000200830600000000500040000030000700000090001 31 | 000000014008005000020000000000020705100000000000000800070000530600140000000200000 32 | 000000014008005000020000000000020805100000000000000700070000530600140000000200000 33 | 000000014008009000020000000000020805100000000000000700070000930600140000000200000 34 | 000000014700000000000500000090014000050000720000600000000900805600000900100000000 35 | 000000014790000000000200000000003605001000000000000200060000730200140000000800000 36 | 000000014970000000000200000000003605001000000000000200060000730200140000000800000 37 | 000000015000400070300060000800000200000104000400500000000023600010000000070000000 38 | 000000015000400070400000000609000300000100800000700000500030200000060040010000000 39 | 000000015000800070300000000408000300000100400000700000500040200000090060010000000 40 | 000000015000800070400000000609000300000100800000700000500030200000060040010000000 41 | 000000015000830000000000200023000800000001000080000000105040000000600720900000000 42 | 000000015000830000000000200026000800000001000080000000105040000000300720900000000 43 | 000000015000900070400000000608000300000100800000700000500030200000060040010000000 44 | 000000015000900070400000000609000300000100800000700000500030200000060040010000000 45 | 000000015000900080300000000704000300000100400000800000500040200000070060010000000 46 | 000000015000900080400000000704000300000100900000800000500030200000070060010000000 47 | 000000015020060000000000408003000900000100000000008000150400000000070300800000060 48 | 000000015040080000000000300000040260500107000900000000300500000080000400000900000 49 | 000000015300600000000000080600050200000001000000000040010200700000760300008000000 50 | 000000015790000000000200000000008706001000000000000900070000830400150000000300000 51 | 000000016000500040300070000900000200000408000700600000000023700040000000010000000 52 | 000000016000708000000000050501200000300000800600000000040000200000053000080010000 53 | 000000016000900080500000000405000300000100500000800000600040200000030070010000000 54 | 000000016040005000000020000000600430200010000300000500000003700100800000002000000 55 | 000000016070000040050200000400060300000005200000041000000900780100000000000000000 56 | 000000016070000040050200000400060300000008200000041000000500790100000000000000000 57 | 000000016200000000000300000601700002000900500400000000030000800000060040050040000 58 | 000000016200080000009000000000420500010000000000000200000106030500000780000900000 59 | 000000017090600000000000030400500200001000000000080000720000600000410500000003000 60 | 000000017090600000000000050200000803000050400000001000600200300041070000000000000 61 | 000000017090800000000000040007060300050000200000001000600300800401000000000050000 62 | 000000017300080000000000000007100006000040300085000000200000840010700000000500000 63 | 000000017600020000000000000153000000000080200007000000400301500020000600000700000 64 | 000000018020500000000000000040000700600000500000041000000700260108300000400000000 65 | 000000018050600000000000030400500200001000000000090000820000600000410700000003000 66 | 000000018200400000000000070000008003000500200010000000502000600000040300000017000 67 | 000000018320000000400000000008051000040000300000070000706000090000300700000200000 68 | 000000018700040000000000030420000700000001000000300000500070200601800000040000000 69 | 000000019000250000000000000091000030000400700030000000400000208200060500000001000 70 | 000000019030050000000000020109000000000400700000870000000102000060000800500000300 71 | 000000019030050000000000020109000000000400800000870000000102000060000700500000300 72 | 000000019070000030200800000050600200001000000000200000000019500600000400000030000 73 | 000000019300600000000000000600080500040000300000010000480000070000200400010900000 74 | 000000019500600000000000000600080500040000300000010000380000040000200700010900000 75 | 000000019500600000000000000600080500040000300000010000480000070000200400010900000 76 | 000000019500800000000000000300070500040000300000010000470000060000200400010900000 77 | 000000019800500000000000000300070500040000300000010000470000060000200400010900000 78 | 000000021000030070040080000100207000050000400000000003200100000000040500000600000 79 | 000000021000083000000040000500200070080000400030900000000060800100500000200000000 80 | 000000021000083000000040000500200070080000400030900000000060800100700000200000000 81 | 000000021000306000000800000400010600000700300200000000000090040530000000086000000 82 | 000000021000407000000008000031060000000000750020000000500210000400000800000300000 83 | 000000021000500030400600000000021000800000007500000600000400800010070000030000000 84 | 000000021004090000070000030100203000500800000006000000200000600000060400030000000 85 | 000000021005080000600000000000670300120000500400000000000201040003000000080000000 86 | 000000021006800000000000070070021000020000400000005000500430600100000000000600000 87 | 000000021030400000700000000100082000000000540000000000000560300290000000004700000 88 | 000000021030600000000080000201000050500400000000370000700002000080000300000000600 89 | 000000021040500000700000000100082000000000650000000000000610400320000000005700000 90 | 000000021040500000800000000700092000000000650000000000000610400320000000005800000 91 | 000000021040600000000000000201000050500800000000400300700020000060000800000300400 92 | 000000021050030000000800000102000070700300000000540000600002000030000400000000500 93 | 000000021060300000000708000100050040070000300000020000200040000000600800500000000 94 | 000000021060500000000090000400002000070000300000600000102400000000030640800000000 95 | 000000021060700000000000000402000000000600300500000700000340050080000600100002000 96 | 000000021070030000000040000100205040030000800000100000200600000000070300600000000 97 | 000000021070030000000090000100205040030000800000100000200600000000070300600000000 98 | 000000021070300000000000000402000000000700300600000800000540060090000500100002000 99 | 000000021070300000000408000100060050030000400000020000200050000000700800600000000 100 | 000000021080300000000409000100060050030000400000020000200070000000800900500000000 101 | 000000021090300000000000000402000000000700300600000700000540060080000500100002000 102 | 000000021090300000000060000201000050500400000000970000600002000080000300000000900 103 | 000000021090700000000000000000514000630000000000002000000600930001040000200000800 104 | 000000021300050000000000000500630000010000080000000500704000600600200000000108000 105 | 000000021300050000000000000500630000010000080000000900704000600600200000000108000 106 | 000000021300050000000000000500830000010000090000000500704000600600200000000109000 107 | 000000021300090000000000000500630000010000080000000500704000600600200000000108000 108 | 000000021300090000000000000500630000010000080000000900704000600600200000000108000 109 | 000000021300700000000000000060500300020000070000000800100040700500012000000006000 110 | 000000021300800000000000000060500700020000040000000300100040800500012000000006000 111 | 000000021300900000000000070200000400000060300000001000071040000000200508090000000 112 | 000000021400300000000000000000010600080000300020007000600000470500120000000800000 113 | 000000021400600000000000000000012800609000000000030000510000030000709600020000000 114 | 000000021400600000000000000000012900706000000000030000510000030000807600020000000 115 | 000000021430000000600000000201500000000006370000000000068000400000230000000070000 116 | 000000021500040000000000070000300600000020500010000000600000203003107000000008000 117 | 000000021500040000000600000031000080000070000020000000600300400405000700000200000 118 | 000000021500400000000000000300000570600080000000010000010605000082000000000007400 119 | 000000021500400000000800000021500000070000600000000030400000800300070000006020000 120 | 000000021503000000600000000000104060700000500000200000000480300010070000200000000 121 | 000000021600000030070900000000043700100000000000020000000600008002100000040000500 122 | 000000021700060000490000000000070900003800000020000000960000800000302000000100000 123 | 000000021700600000300500000000082000040010000500000000020040000000300700000000650 124 | 000000021750000000000000000070000890000201000000400000030090500100030000400000600 125 | 000000021800040000000000060090200000700000400000501000015000000000030900602000000 126 | 000000021800400000009000000600570040300000800000020000070900400021000000000000000 127 | 000000021800500000000060000030102000500000840000000000000780500620000000004000000 128 | 000000021800600000000050000030102000500000840000000000000780500620000000004000000 129 | 000000021800700000400005000023000060000800500010000000600000700000081000000030000 130 | 000000023000500080000100000020000900000400100580000000600009500000020070001000000 131 | 000000023000800010800400000032500000000000100070000000600070004100000500000003000 132 | 000000023010040000500000000100000400000200080000803000000050160040000700003000000 133 | 000000023010040000500000000100000400000200080000903000000050160040000700003000000 134 | 000000023010040000500000000100000400000600090000203000000050170040000800003000000 135 | 000000023010800000000000060300020000050000700000400000000507100002010000600000400 136 | 000000023080000070400020000030002000000000401000060500100000600000807000000300000 137 | 000000023080000070500090000030002000000000401000060500100000600000807000000300000 138 | 000000023300010000000500060400000700000106000000200000092000100000040800060000000 139 | 000000023400800000100000900050032000000000400000060000000401800030000050000900000 140 | 000000023400800000100000900050032000000000400000070000000401800030000060000900000 141 | 000000023480000000010000000503000060000010800000000000170000400000602000000300005 142 | 000000023600010000000400000000080700502000000000000100080203000010000640000500000 143 | 000000023600700000000000080000038500200000800000010000000200640003400000010000000 144 | 000000023800000050000100000010600400507030000000000000300052000064000100000000000 145 | 000000024000010000000000080107000900300800100000200000020400060500070300000000000 146 | 000000024000010000000000080307000100100800500000200000020400060500070300000000000 147 | 000000024000080010600005000000300700040700000010000000000040501300600000200000000 148 | 000000024007000000006000000500090100000300600020000000940000050000607300000800000 149 | 000000024010008000000070000600201500400000003000000000070000810500430000000000000 150 | 000000024010300000060000000050000300000082000700000000400100500200000063008000000 151 | 000000024010300000070000000060000300000029000800000000400100600200000075009000000 152 | 000000024010300000070000000060000300000082000500000000400100600200000075008000000 153 | 000000024100000000000600000000180700020000009030500000500070600004002000000000030 154 | 000000024100000000000700000000560800020000009030100000600080700004002000000000030 155 | 000000024100800000000000003000400500700000100000030000000510600002000050030007000 156 | 000000024600800000100000000000040010070000300040600000520004000000000806000070000 157 | 000000024700000060000900000004001000020050000000030700000400800300000500600200000 158 | 000000024900700000000000000800000730000041000000000000002500800046000300010020000 159 | 000000025000000070800000000600000103000070400000020000053100000020005000000600300 160 | 000000025000800010400000000050000700000300600010000000600020400800007000000015000 161 | 000000025000800010900000000050000700000300900010000000600020400800007000000015000 162 | 000000025030006000000090000000740000600500000020000700000208300504000000000000100 163 | 000000025050000040000100000207000000300000070000800600089000100000002700000040000 164 | 000000025080000600000001000300400700000050008000000000000280400107000030000500000 165 | 000000025190000000000600000006030700000000100002000000400205000060000340000800000 166 | 000000026000080040000500000100600700300000080000020000000703100042000000000000500 167 | 000000026000080040000500000100600700300000080000020000000903100042000000000000500 168 | 000000026040700000000000001000900800400000500001000000000012050070000300300060000 169 | 000000026080003000000070000100400800605200000007000300030000900000050000000600000 170 | 000000026501000000000000000070206000300000150000800000020700000000000540000010300 171 | 000000026800500000000000704300070100000040000000000030000300810040900000060000000 172 | 000000026800700000000000005700030100000006500000020000026400000000000810030000000 173 | 000000027000051000000000600504000100000200000300000000020740000060000039000000500 174 | 000000027010900000500000060000300400600000050000000008049000100000026000000000300 175 | 000000027010900000500000060000300400600000050000000008094000100000026000000000300 176 | 000000027040800000000000001000400900600000500001000000000012050080000300300070000 177 | 000000027300000040100000000000605100000100500040000000070020030008000600000040000 178 | 000000027300000040100000000000605100000100500040000000070040030008000600000020000 179 | 000000028000050000000040000708200000040000300000600000600801000030000450000000900 180 | 000000028000070040000300000074000050000600300000001000630000100200040000000000600 181 | 000000028000500060010000000506020000400000300000000100000100700000403000680000000 182 | 000000028000800030100000000000070400080600000035000000700060100000000705000300000 183 | 000000028030000050600000000100050604000062000000000700028000000000700300000100000 184 | 000000028070009000000000003000302000040000500000000000800050100000040760300600000 185 | 000000028300000070000100000000080030049000000050000600000604100000500400200000000 186 | 000000029000306000000000008060000500053000000000020000000600150200070400900000000 187 | 000000029000600070010000000507020000400000300000000100000100800000403000790000000 188 | 000000029000730000000050080000600700082000000000000100400100600000002050100000000 189 | 000000029000730000000400060203000400000100300600000000080050100000002000010000000 190 | 000000029000730000000400060208000300000100500600000000070050100000002000010000000 191 | 000000029000830000000400070203000600000100300700000000040050100000002000010000000 192 | 000000029000830000000400070203000600000100300700000000080050100000002000010000000 193 | 000000029300600000000080070800000600000021000000000100029000000000800030000400500 194 | 000000029300700000000800040600000700000042000000000100049000000000010050000300600 195 | 000000031000079000000000000013200000004000700000100000500040670280000000000300000 196 | 000000031000407000000600000600300000407000000500080000030010000020000700000000450 197 | 000000031000602000000700000007000600010080000400030000000500270140000000800000000 198 | 000000031004020000080000000100300000000008200600000000020000740300510000000600000 199 | 000000031004020000080000000600300000000008200100000000020000740300510000000600000 200 | 000000031004020000090000000700300000000008200100000000050000840300610000000700000 201 | 000000031005020000080000000700300000000008400100000000040000250300610000000700000 202 | 000000031007020000080000000100300000000008200600000000020000740300510000000600000 203 | 000000031007020000080000000600300000000008200100000000020000740300510000000600000 204 | 000000031007020000080000000600300000000008200100000000040000720300510000000600000 205 | 000000031008020000070000000600300000000008200100000000020000740300510000000600000 206 | 000000031008020000090000000600300000000009200100000000040000720300510000000600000 207 | 000000031008020000090000000700300000000009400100000000050000240300610000000700000 208 | 000000031020500000000000000301070000000400200700000500070200600800010000000000080 209 | 000000031020700000008500000000016200400030000050000000300000050000200700000040000 210 | 000000031028000000000000000000208400730000060000500000160070000000400200300000000 211 | 000000031040060000000009000060005200000300070500000000308100000000020400000000700 212 | 000000031050060000000007000070004600000300050600000000403100000000020500000000800 213 | 000000031050070000000009000070006400000300050600000000403100000000020500000000800 214 | 000000031050080000000000000600307000040000500000100020100000800000050400003200000 215 | 000000031060040000000000000002801400500300010000007000000050600730000000100000000 216 | 000000031060200000000708000300050040070000200000010000100040000000600800500000000 217 | 000000031060400000000000000500037000090000200000001000700840000000600490100000000 218 | 000000031060500000000020000000460500300007000800000000000700080100003000020000600 219 | 000000031080000070000920000401000000000200800300000000090000250000080600000001000 220 | 000000031080040000070000000106300070300000000000080000540000800000600200000100000 221 | 000000031080400000600000000000200840700600000100000000500073000090000200000010000 222 | 000000031080600000000070000000700290500400000300000000020050800000031000400000000 223 | 000000031200040000000000000031700080000020500400000000000803000500000200000100600 224 | 000000031200070000000009000000301040600400000708000000000060200030500000000000700 225 | 000000031200080000000400000031005060000720800000000000000603000400000200700000000 226 | 000000031200700000400000000038000060000400300010000000000514000700000200000080000 227 | 000000031280000000000000000003610000000004270000000000420000800500070400000300000 228 | 000000031280000000500100000000037800600000200000040000030000040100500000000600000 229 | 000000031400020000000007000000301050700500000206000000000080200030600000000000400 230 | 000000031400020000000009000000301050600500000208000000000070200030600000000000400 231 | 000000031400020000000009000000301050700500000204000000000080200030600000000000400 232 | 000000031400020000000009000000301050700500000206000000000080200030600000000000400 233 | 000000031400020000010500000000300060200006000800000000000700800060000200039000000 234 | 000000031400070000208000000700000200000300000000900000630000090000580400000020000 235 | 000000031500070000000006000700000560001400000020000700600000800030100000000200000 236 | 000000031600008000000050000000370020580000000060000000200000600007100000000400800 237 | 000000031600020000000070000050108000200000600000300070000040200030500000700000000 238 | 000000031600200000000090000000080290310000000400000000049000500000603000000700000 239 | 000000031600800000000000000030000850020010000000400000804000600006030000700005000 240 | 000000031700020000000006000040100050030080000000000200600400900200005000000300000 241 | 000000031700200000000480000000700800030000000060000000000039060520000400800000000 242 | 000000031700200000040000000502700060000800700030000000000093000200000500000010000 243 | 000000031740000000000000009000003460200000500000090000000570800030800000001000000 244 | 000000031800020000200000000037100060010080500000000000500400800060300000000000000 245 | 000000031800060000000000000600000470000100600500200000023500000000070800010000000 246 | 000000031800900000000000040400000800000060200000001000031050000000200407090000000 247 | 000000032000100000050000000040000800000310000000602000300000760000080500802000000 248 | 000000032000100000060000000803000000000600900000007500000580070040000100200030000 249 | 000000032010000000000300000309700000000060100800000400200000080000540000000016000 250 | 000000032010040000000000000000307020084000000600000000000080104700100500300000000 251 | 000000032010040000000000000000703020084000000600000000000080104700100500300000000 252 | 000000032040000000900000000302700050000100800600000000070000100080060000000030006 253 | 000000032480000000010000000503000060000010800000000000170000400000602000000300005 254 | 000000034000100000000000060070000200005003000040050000000740100300000800600200000 255 | 000000034000100007800000090980000200600040000000700000000009800007030000010000000 256 | 000000034060200000000000070000960800301000000700800000070003000900000200000010000 257 | 000000034080100000000000060000039000000040800001000000360200000400000700000700500 258 | 000000034100000000000000050020050700043000000000010000900600800000400100000302000 259 | 000000034500000010000070000405310000000000200100000000000600700087000000020400000 260 | 000000034500900000000000000004700100060000200038000000200000507000036040000000000 261 | 000000034600900000000000000004700100050000200038000000200000607000043050000000000 262 | 000000034700005000000000010000087200000020500010000000200300060001400000000000900 263 | 000000034800600000000100000605000100000040070200090000043000000000000201090000000 264 | 000000035000020070000010000000240000800000600100000000020507000000300800070000100 265 | 000000035040000080100000000007000200000085000600000000000400106030100700008000000 266 | 000000035200100000080000000040000700000200040005003000300070006000040200000000100 267 | 000000035490000000010000000603000070000010900000000000180000400000502000000300006 268 | 000000036000000020800000000700000104000030500000020000064100000030006000000700400 269 | 000000036000500040000700000000200705108000000600000000340060000050000200000010000 270 | 000000036000500040000700000000200705108000000600000000340060000070000200000010000 271 | 000000036007100000000040050405003000000700200000000100010200800300000000090000000 272 | 000000036030000050200000000000060800700000400000053000000700210060900000001000000 273 | 000000036040200000010000000000004019008000200600030000700050000000100800300000000 274 | 000000036200030000500000001400070200010000000000000080308000400000501000000600000 275 | 000000036200030000500000001700080200010000000000000080309000400000501000000600000 276 | 000000036800010000000020000030602000000000190000500800100000900060000070000300000 277 | 000000036800700000000000090090000001060000020000500400000039000004000800700000500 278 | 000000036840000000000000020000203000010000700000600400000410050003000200600000000 279 | 000000036900040000000000010000103000200000400000600050007500200000060800010000000 280 | 000000037002000050010000000000200104000001600300400000700063000000000200000080000 281 | 000000037004600000000000010078000200000007500000010000310000020000800600400000000 282 | 000000037040600000000000010096000200000005800000010000107000050000400600300000000 283 | 000000037060000040500000000100040502000083000000000600037000000000500100000200000 284 | 000000037400200000000000000107000040000800200300500000000031000080000500060000400 285 | 000000037500000040090000000000510200003000900060000000200000160000703000000800000 286 | 000000037900040000000000010000103000200000400000700060006500200000070800010000000 287 | 000000038000000710900400000000017000600000900000003000000650200003000060010000000 288 | 000000038000009001000500020000460500800200000100000000040000600000021000700000000 289 | 000000038000020000000090000800000200000600100007300000000701060290000500040000000 290 | 000000038060020000007000050500400000000060700000000100100508000040000600000300000 291 | 000000038090200000000000510740000600000003070000010000005600200003000000100000000 292 | 000000038200050000000400010800000600000001000000200000041000500000620700030000000 293 | 000000038200400000000070010800000500000001000000200000071000400000520600030000000 294 | 000000038600001000000000050100200700800000004000750000025030000000000100030000000 295 | 000000038700040000000000010000108000200000600000300040006500200000060700010000000 296 | 000000039000070080000140000600000500200600000000003070000200600083000000000000100 297 | 000000039000140000000060080000500200083000000000000100500200700000003060200000000 298 | 000000039000140000000080070000500200037000000000000100500200600000003040200000000 299 | 000000039000140000000080070000600200037000000000000100500200600000003040600000000 300 | 000000039000600040800100000500000600000020070000004000000280700043000000000000100 301 | 000000039000740000000050080000600700083000000000000100100200600000003050200000000 302 | 000000039000740000000050080000600700083000000000000100100200600000003050600000000 303 | 000000039500070000000000010000503000400000200000600000003000860000240700010000000 304 | 000000039700400000003000010480000200000030700000001000040600500000000020000090000 305 | 000000039700400000003000010680000200000030700000001000040600500000000020000090000 306 | 000000039700400000003000010840000200000030700000001000080600500000000020000090000 307 | 000000041000062000000000000000710030602000500500000000310400000000008200040000000 308 | 000000041000700000300000000000045060700000300020010000000800200045000000601000000 309 | 000000041000700000300000000000045060700000800020010000000900200045000000601000000 310 | 000000041005080000600000000000670200410000500300000000000104030002000000080000000 311 | 000000041007300000000000520000800300420000000500000007060004200000010000008000000 312 | 000000041009300000000000520000800300420000000500000007060004200000010000008000000 313 | 000000041020000050800000000000280700060030000001000000300000807000501600000000000 314 | 000000041020060000800070000300400600000002000000100000000030700010500000005000030 315 | 000000041020500000000000000000084060570000000000000200000120300804000000600700000 316 | 000000041020500000000000000000094070580000000000000200000620300904000000700800000 317 | 000000041020700000000000000400013000070000200600000000000270500103000060000800000 318 | 000000041050080000000000000600107000030000500000400020400000800000050300001600000 319 | 000000041050800000090000000000007020000041000000000503700260800100000000000300000 320 | 000000041050900000070000000000008020000041000000000503800760900100000000000300000 321 | 000000041060800000000300000200054070080000000000001000000630800700000200400000000 322 | 000000041060900000070000000000008020000041000000000305800720600100000000000300000 323 | 000000041070060000030000000400201050060000700000800000000050300100400000200000000 324 | 000000041070200000000308000400060050020000300000010000100050000000700800600000000 325 | 000000041080030000200000000500060700002000300400008000000500020010400000000000800 326 | 000000041080070000030000000600201050070000800000900000000050300100400000200000000 327 | 000000041090700000000080000000800290600500000400000000030060900000041000500000000 328 | 000000041200500000000007000500000200000040600000036000034000000010000030000800500 329 | 000000041200600000530000000700080300000041000000000060008300000000500200040000000 330 | 000000041200700000000000006000300800090000500060040000700000230300060000000001000 331 | 000000041300020000000500000015000000000070600080000000600000370200104000000800000 332 | 000000041320000000500000000600300200004000080000500000200000300000081000000740000 333 | 000000041500020000000800000018000000000030600090000000600000350700104000000900000 334 | 000000041500300000200000000000260300010000060700500000080041000000080200000000000 335 | 000000041500900000070600000000350600402000000800000000000040080090000300030000000 336 | 000000041520000000000030000000070530100800000400000000600105000030000200000400000 337 | 000000041600000000000800000500600200040000070000300000000071600002000300070040000 338 | 000000041600300000000020000040100080000506000700000000300000500000070300010004000 339 | 000000041630000000000800000010000070070030000000020500500104000200000600000700000 340 | 000000041700050000200000000000801030650000700000400000081600000000020900000000000 341 | 000000041700090000200000000030104000040200000008000500100050600000000080000000700 342 | 000000041700600000200500000000081000030040000500000000010030000000200700000000650 343 | 000000041800020000000000000040509000007000200000000800600000390200410000000700000 344 | 000000041800050000200000000000701030650000200000400000071600000000080900000000000 345 | 000000041800500000000000000200000860070140000000030000600008200000300500040000000 346 | 000000041900300000000000000300200800000010060200000000067040000010050000000800200 347 | 000000041900300000000000000300200900000010060200000000067040000010050000000800300 348 | 000000041900500000000000000200000960080140000000030000600009700000300500040000000 349 | 000000041900600000000200000000810300540000000002000000031040000700000600000000020 350 | 000000041900700000000000000200000960080140000000030000600009700000300500040000000 351 | 000000042000500080000001000000900300200000100400080000090060050010000700000800000 352 | 000000042100700000000000080600300500040000020000100000000060105090040000000000300 353 | 000000042100800000000000070600300500070000020000100000000060105090040000000000300 354 | 000000042500090000000000000006100700000030800024000000390000000000004006000200050 355 | 000000042600900000000000030500000800007600000020040000000508100034000000000000700 356 | 000000042650000000000800000100000600000045000700002000000100780002030000040000000 357 | 000000043000015000000200000000420000050000600000900000000008170403000000200000800 358 | 000000043000015000000200000000420000090000500000800000000007160403000000200000700 359 | 000000043000080050000001000700500600000304000100000000040200000000070100030000900 360 | 000000043000800070000020000060500800000304000001000000370000200000010900400000000 361 | 000000043010050000000000000000408030095000000700000000000090105800200600400000000 362 | 000000043010050000000000000000804030095000000700000000000090105800200600400000000 363 | 000000043050200000080009000060000800100030000000000000307510000000800200400000000 364 | 000000043100200000000000000000600700030000200005080000270100000000030065900000000 365 | 000000043200700000000000080600200500040000030000100000000060205090040000000000100 366 | 000000043200800000000000070600200500070000030000100000000060205090040000000000100 367 | 000000043500080000000000010000370500010000000000000200000104020005700000800000600 368 | 000000043800050000000000010007600200000080700010000000000104020600000500000300000 369 | 000000045000800020100000000005620000700000004000000700086000100000045000030000000 370 | 000000045700200000000100000106000200000050060300080000054000000000000302080000000 371 | 000000045800200000000100000106000200000050070300090000054000000000000302090000000 372 | 000000046000070010060020000108000000000500300400000500030000200000108000000400000 373 | 000000046000500010500000000709000300000100800000400000600030200000070050010000000 374 | 000000046000500010500000000709000300000100800000400000600030200000090050010000000 375 | 000000046000800010500000000709000300000100800000400000600030200000070050010000000 376 | 000000046000800010500000000709000300000100800000400000600030200000090050010000000 377 | 000000046005800000000000020160000300000300500020000000000267000309000000000040000 378 | 000000046020000300001000000000001730600000008000000000030000210400680000000500000 379 | 000000046020000700001000000000001830600000009000000000080000210400690000000500000 380 | 000000046050010000000000000000408030017000000600000000000070102300200500400000000 381 | 000000046100000000000000080000130200084005000000700000060084000300000100000200000 382 | 000000046700010000000030000040603000000000190000800700100000900020000080000400000 383 | 000000047010050000000000000000408030065000000700000000000060102300200500400000000 384 | 000000047300500000000000010709000600000010000000000200000200705041008000030000000 385 | 000000048600200000000700010000040060500000300002001000000350700010000000000000200 386 | 000000049000050060000030000400900000700800000000000300503000100060000200000702000 387 | 000000049700200000000800010000040070500000300002001000000360800010000000000000200 388 | 000000051000036000000000000040500080200000600000001000000020340010400700600000000 389 | 000000051000083000000040000600500020080000400030900000000070800500600000200000000 390 | 000000051000203000000400000050080060094000000000000300302000600700000200000050000 391 | 000000051000307000000008000021060000000000740050000000400150000300000800000200000 392 | 000000051000307000000800000500010700000600300200000000000090020430000000087000000 393 | 000000051000308000000100000090050040020000100000000000601700800400020000500000000 394 | 000000051000308000000100000090050060020000100000000000601700800400020000500000000 395 | 000000051000309000000100000080050040020000100000000000601700300400020000500000000 396 | 000000051000309000000100000080050060020000100000000000601700300400020000500000000 397 | 000000051000402000800070000200600400700000030000500000000030200016000000050000000 398 | 000000051000402000800070000200600400700000080000500000000030200016000000050000000 399 | 000000051000702000000400000050080030084000000000000700302000600700000200000050000 400 | 000000051020060000700040000640000300000105080200000000001800000300000600000000000 401 | 000000051020070000000000000000145000040000890000300000109500000000060200300000000 402 | 000000051020400000000000000000390200500080000000000400040600700100050080000200000 403 | 000000051020600000000000000000300780400900000100000000070005200600010000000040600 404 | 000000051020600000000000000070000200300050000000040800501000030400008000000200600 405 | 000000051030800000000000000000400830100700000200000000040006300700020000000010900 406 | 000000051040006000000300000105030000000000820700000000620000400000750000000100000 407 | 000000051040700000000000000000013700500020000060000400000600840100800000200000000 408 | 000000051040700000000000000090000700000051000000060030000406200300000800506000000 409 | 000000051040900000000300080107050000030000200000000000000209300605000000800000000 410 | 000000051060007000000030000000006200700000030500100000014000600000850700000000000 411 | 000000051060007000000030000000006200700000030500100000024000600000850700000000000 412 | 000000051060020000000000000000145000040000780000300000108500000000060200300000000 413 | 000000051060020000100700000000500030020030000040000000300000200000800400509000000 414 | 000000051060400000000000000000380600500070000000000400040600300100050070000200000 415 | 000000051060400000000000000000390600500080000000000400040600700100050080000200000 416 | 000000051070030000800000000000501040030000600000800000500420000001000300000000700 417 | 000000051080200000000000000930000800000014000000500000401000070000600200000380000 418 | 000000051080400000000000000000031009507000000040000000000700460100200000300000800 419 | 000000051090030000000000000070400620000501000000800000000070300504000000200000400 420 | 000000051090700000000000000000400930100500000200000000080006300700010000000020700 421 | 000000051200030000000000000000070620050400000000000300004501000600000830000700000 422 | 000000051200060000000000000000080720050400000000000600004501000600000230000800000 423 | 000000051200080000040030000017200000000000630000000400000507000600000300000100000 424 | 000000051200600000000800000071050000040300200000000600000010040600000300800000000 425 | 000000051200600000000800000071050000040300600000000200000010040600000300800000000 426 | 000000051200800000400000000010057000300000200000060400057000060000200300000000000 427 | 000000051260000000008600000000071020040050000000000300000300400500900000700000000 428 | 000000051300020000000800000042000000000090600010000000600000390700501000000400000 429 | 000000051300040000200000000056100000070600000000030800010500060400000300000000000 430 | 000000051400030000000800000250100000300000740000006000000040300060007000010000000 431 | 000000051400070000200000000037006400008000000000500000000020780510300000000000000 432 | 000000051400200000000000000000406200050300000070000000000075030608000400000010000 433 | 000000051400800000200000000010057000300000200000060400057000060000200300000000000 434 | 000000051460000000080000000000050670001020000300000000050000400200300000000109000 435 | 000000051600003000090040000012500000000007900400000000500000780000020000000100000 436 | 000000051600030000000000000000504090802600000000001000000020800700000300050100000 437 | 000000051600200000000000000000406200050300000070000000000075030408000600000010000 438 | 000000051700200000003000000004058000000010600600000200010000080260000000000300000 439 | 000000051700200000800000000054010030010030000000000200200700600030000000000000700 440 | 000000051800020000300000000017600000000030200050000090400700800060500000000000000 441 | 000000051800070000300000000040080700000400000005000000006501000030000870000000200 442 | 000000051800070000300000000040080700000600000005000000006501000030000870000000200 443 | 000000051800200000000000000040070300000051000090000000000309200507000060100000000 444 | 000000051800200000400000000010095000000000840030000000000760300250000000000800000 445 | 000000051800300000000000000520010000300000790000006000067000400000400300010000000 446 | 000000051800700000300600000000012000090050000600000000010040000000300800000000760 447 | 000000051803000000000000000250400000010000700000020300000506040007000200000100000 448 | 000000051900200000000000000451060000000400380000000000240000700000003200000050000 449 | 000000052000700040100000000010600000000030800024000000000200100000405000300000600 450 | 000000052000700040100000000010600000000030800042000000000200100000405000300000600 451 | 000000052003400000070000000030005600000020010000081000200000008000600700100000000 452 | 000000052005400000070000000030005600000020010000081000200000008000600700100000000 453 | 000000052009400000070000000030005600000020010000081000200000008000600700100000000 454 | 000000052400060000000000010070200000600000400000108000018000000000030700502000000 455 | 000000053000008010300400000000015020700000400006000000000720600010000000000000200 456 | 000000053000400006080000000506000700000010400300000020010000200000305000000700000 457 | 000000053160000000000000000400000607000305000000800000000024100003000020070010000 458 | 000000053600700000000000020000039500200000800000010000000200640003400000010000000 459 | 000000053700600000000000040024000000008050000000300000010040200600007000300000600 460 | 000000053800060000000000070000200800000705000100000000072003000000610400050000000 461 | 000000054000803000000000000105040000000200930600000000500007000000010002030000800 462 | 000000054010700000200000000000056000030000700080000000600100300004000072500000000 463 | 000000054010900000200000000000056000030000900070000000600100700004000082500000000 464 | 000000054070300000200000000010000700000045000000208000000670100800000300500000000 465 | 000000054100300000000000000000700300040000200006080000320100000000040076900000000 466 | 000000054200070000000010000060000730005400000000000000710000200800300000000500009 467 | 000000054300020000000000010003700200000080600010000000000105030600000800000400000 468 | 000000054300800000000000010041000060030008000000900700905000800000010000000000200 469 | 000000054700020000000010000060000730005400000000000000170000200200300000000500008 470 | 000000054700030000000000000000400016380070000020000000000500800105000000006000300 471 | 000000054900700000000000060006052000800000300000000700020300100040070000005000000 472 | 000000056003800000400000000000062000000000410000000300000450100060100000720000000 473 | 000000056080010000002000030000203000300600000010000900600700000000080400000000100 474 | 000000057000040000000000003000307060800500400100000000000080100070000200030600000 475 | 000000057000080010070020000301000000000600400500000600040000200000103000000500000 476 | 000000059000130000000000000340000020050009000000800600800000307000054000000000100 477 | 000000059700600000000300000059001000020040000000000130807000300000050000400000000 478 | 000000061000027000000000000704000200000100040300000000510000700000048000090600000 479 | 000000061000203000000700000005060400000002300100000000000540080320000000700000000 480 | 000000061000320000500000000230000700000801040900000000001604000000030200000000000 481 | 000000061000400080300000000000020540010000000800000000700800300005000200000603000 482 | 000000061000704000000000000500400700602000050100000000000016000080020000030000900 483 | 000000061000704000000000000500800700602000050100000000000016000090020000030000800 484 | 000000061000800000400000000000300780160500000200000000030060000000020400080000300 485 | 000000061000904000000000000500400700602000050100000000000016000080020000030000900 486 | 000000061000904000000000000500700400102000050600000000000061000080020000030000700 487 | 000000061000904000000000000500700400602000050100000000000016000080020000030000700 488 | 000000061005700000020000000000430500100060000980000000600008010000500700000000000 489 | 000000061009800000000000000004020500030000800000006000000700430160300000200000000 490 | 000000061020500000000000000100064000050000200800000000000250300601000040000700000 491 | 000000061030200000000000000106050040000700300500000000400300200080000700000010000 492 | 000000061030400000000000000600300780105000000000900000200010000040000300000050400 493 | 000000061040050000000007000070003500000100040500000000301600000000020800000000400 494 | 000000061040300000000500090108060000030000200000000000000205300706000000900000000 495 | 000000061040300000000500090108060000050000200000000000000205300706000000900000000 496 | 000000061043000000000000000020008300600070050100000000700160000008000400000500000 497 | 000000061050020000000000000000000250600400000000070300020000530400601000000800000 498 | 000000061050030000000000000000000250600400000000050300020000730400601000000800000 499 | 000000061050030000000000000680040700200600000000000500900106000000000380000200000 500 | 000000061050090000000000000200000070000080500601000000000700320090000400000602000 501 | 000000061050700000200009000000800300401000000600000000000060080030040000020000700 502 | 000000061070005000400030000300000200000100070000800000001600000000070400500000300 503 | 000000061070040000000000000102006000000080300500000000030000740600501000000200000 504 | 000000061070500000000000000900460000050000200000000700601000030300200000000708000 505 | 000000061070500000000400000603050000000200100000000040200006000000039000010000800 506 | 000000061070800000500090000000600300302000000400000000000030040010002000060000900 507 | 000000061200030000000000000000070240060500000000000300005601000300000820000700000 508 | 000000061200030000400000000020801000500600700000000040081000000000070400003000000 509 | 000000061200300000000000000000160000020040000800000300060000740000800200003500000 510 | 000000061200500000800000000000200700037000000060400000100000200000038000000060040 511 | 000000061200500000800000000000200700037000000060400000100000200000068000000030040 512 | 000000061200700000000800000013060000050400200000000700000010050700000400800000000 513 | 000000061200700000000800000013060000050400700000000200000010050700000400800000000 514 | 000000061200800000000000000000402800063000000000700000000036200410000000000010050 515 | 000000061300020000000700000017000000000080500090000000500000380600401000000900000 516 | 000000061300700000090400000710080000000300400000000020000062000500000900000010000 517 | 000000061300800000000000000500000400000014000000070800010620000000500390007000000 518 | 000000061350000000400050000020000800000601000000700000000080200600400000007000010 519 | 000000061400003000000700000010690000020000300000000000304000200000180050700000000 520 | 000000061400030000000500000026000080000070000010000000500200300304000700000100000 521 | 000000061400070000000090000000608200901000000200100000000050400060300000000000090 522 | 000000061400070000020000000061500000000030740500000000005108000700000400000000000 523 | 000000061400200000900000000067015030010070000000000400200800500030000000000000000 524 | 000000061402000000030000000380000400000602000000100000006500000100000070000080300 525 | 000000061403000000020000000308000400000602000000100000060500000100000070000080300 526 | 000000061480000000000000000000520400000030000060000000530006070200000800000107000 527 | 000000061500020000970000000061400000000050900000000080000806000300000500000700000 528 | 000000061700020000000000000060530000010000200000000400000107030208000000400300000 529 | 000000061700400000800000000000720400300000000000010000009800700010000500060000020 530 | 000000061800007000000020000032100000000650800000000000000003720910400000000000000 531 | 000000061890000000000000000000520400000030000060000000530006070200000800000107000 532 | 000000061890000000000000000000520400000030000060000000530006070200000900000107000 533 | 000000061900200000000400000070068030200000700000010000006050000000900200040000000 534 | 000000062800300000000000050040200100060000040000000700001056000700000300000040000 535 | 000000063000100000200000000050000100000400200009006000630090000000200740008000000 536 | 000000063000500004080000000603000700000010500400000020010000200000406000000700000 537 | 000000063020040000000001000040000210000370000000500400503600000000000700800000000 538 | 000000063020040000000001000040000210000370000000500400803600000000000700500000000 539 | 000000063800090000000000010005020400010000000000000200200600500000103070000400000 540 | 000000064005800000000000020160000300000300500020000000000267000309000000000040000 541 | 000000064300800000000000010041000070050008000000900500906000800000010000000000200 542 | 000000064500080000000000010000305700010000040000070000708000200000600800000100000 543 | 000000065000300000000010000000040170509000000000000800270500000010000300000906000 544 | 000000065000710000040000000000053000080000200000000100003200700506000000100800000 545 | 000000065040800000000000001006000800030000700000010000000700230400002000501000000 546 | 000000065900200000000000000000900240053000000000000000060057000100006800000030900 547 | 000000067003900000010000004600004000050010000000000100000800520007000300400000000 548 | 000000067060200000000000040000860300401000000700900000070004000900000200000010000 549 | 000000068030070000100000020070000450000208000000400000000030100200600000000000900 550 | 000000068030070000400000020070000450000208000000100000000030100200600000000000900 551 | 000000068030090000700000020010000350000208000000400000000030100200600000000000500 552 | 000000068100000000000000030060030000000400100008000200400200500730000000000108000 553 | 000000068350000000000010000100000500000800400009000000060205000000400300007000010 554 | 000000068350000000000010000100000500000900400006000000070205000000400300008000010 555 | 000000068900000002000400500041000000000035000050000000000800010300000700000100400 556 | 000000069070000040050800000000507200300100000600000000000030008400060000000000500 557 | 000000069800040000000010000000300800010000400650000000701000200000905000000600000 558 | 000000071000040000600000000000705000200000600000100300087000050010300000000060400 559 | 000000071000052000000000000000008540710400000300000000460070000005000200000300000 560 | 000000071000208000000600000501000000000300200700000000030040600260000000000070050 561 | 000000071000520000000000000000070080300001000204000000500600200000300600070004000 562 | 000000071000580000000000000000031060200400000508000000070006000030000500000100200 563 | 000000071000604000000000000500400600102000050700000000000071000080020000030000900 564 | 000000071000604000000000000500800600102000050700000000000071000090020000030000800 565 | 000000071000800000000300000040000300270000000000500800600070500008060000000010040 566 | 000000071000904000000000000500400600102000050700000000000071000080020000030000900 567 | 000000071002500000000000000780000030000420000000100000050007200004600500300000000 568 | 000000071005020000040000000100300000000009400800000000060000950300710000000800000 569 | 000000071006090000000000050102000000000060300050000000070504000800000600000200400 570 | 000000071020400000500000000080000600000037000000010000000600240300500000109000000 571 | 000000071020400000600000000080000200000037000000010000000200540300500000109000000 572 | 000000071020600000000000000100073000060000200500000000000260400703000050000800000 573 | 000000071020800000000403000700060050000200300900000000600070000080000400000050000 574 | 000000071030020000000000000000000250600100000000080300020000530400601000000700000 575 | 000000071040050000000600000000100600080000500000007003107000060000080200300000000 576 | 000000071050003000040080000030000500200100000600000000000040300700000040100600000 577 | 000000071050008000000000000060040030200170000000300600000002500401000000700000000 578 | 000000071050080000000000000600103000020000890000400000000700200100040000403000000 579 | 000000071050600000200009000000800300407000000100000000000010020030040000020000600 580 | 000000071060005000000000000080000630400170000000200000907020000000003800000000500 581 | 000000071060020000000030000700060300400000200100400000000105080020000000000700000 582 | 000000071060020000000030000700060300400000200100400000000705080020000000000100000 583 | 000000071060020000300000000050000260000108000000300000000430500108000000007000000 584 | 000000071060030000000020000700060300400000200100400000000105080020000000000700000 585 | 000000071060030000000020000700060300400000200100400000000705080020000000000100000 586 | 000000071060300000500000000000040050007010000020000600000500900400600000801000000 587 | 000000071060500000000000000005040600030000200000007000000800540107300000200000000 588 | 000000071080300000000200000407020000000600800100000300500070040030000600000000000 589 | 000000071080400000000500000100072000050000630000000000000380400207000000600000000 590 | 000000071090800000000000000400300600701000050000902000060000300500070000000000900 591 | 000000071200050000030060000701300000000000640800000000000107000040000500000002000 592 | 000000071200300000860000000000500630004200000700000000000071000050000800000040000 593 | 000000071200600000300000000000510007604000200000008000050000040000200600010000000 594 | 000000071200900000000000000000600830071400000500000000640000200000050600000007000 595 | 000000071300200000000000000000060300010030000004000000600000540000407200800100000 596 | 000000071300200000000400000000078040200000300050010000400000500007060000000500000 597 | 000000071300500000000000000000308500002600000070000000000070320800050000010040000 598 | 000000071300500000600400000000072000080010000400000000070020000000300600000000540 599 | 000000071300800000080000000005041000020000300000070000601000040000200600700000000 600 | 000000071400030000000200000020700000000040300000000500000102060308000400500000000 601 | 000000071400080000000000000000170050820000000300000000001703000600000800000500400 602 | 000000071400500000600000003050037000200000800000010000000800040000400200010000000 603 | 000000071400900000300500000000300450070060000000000900000072000080010000500000000 604 | 000000071500020000000800000047000000000090600010000000600000250700103000000400000 605 | 000000071500030000000600000600000800200400000000702000000080300041000000070000020 606 | 000000071500400000300000000400306500010000060000200000080000200000017000000080000 607 | 000000071580000000030900000407200000000000810060000000200000500000067000000010000 608 | 000000071600040000000000000087500000000020900010000000300800600406000020000100000 609 | 000000071600200000800000000070031040000600500200000000030070000000500600000000200 610 | 000000071600200000900000000400650300010000080000400000070081000020000600000000000 611 | 000000071600500000040000000502600030000900600070000000000013000800000900000070000 612 | 000000071600500000200000000340010000000070620000000500000600300080400000010000000 613 | 000000071600500000300400000000072000080010000400000000070020000000300600000000540 614 | 000000071800020000300000000076500000000030200010000090400600800050100000000000000 615 | 000000071800030000000000000670200000000090300000000500020701000500000830000400000 616 | 000000071800040000000000000070200000030000800000090400000701030400500600900000000 617 | 000000071800040000000000000670200000000090300000000400020701000300000840000500000 618 | 000000071800300000400050000670000500000012000000400000002000050000800400010000000 619 | 000000071900000060020000000004070000030000400000910000700600008000300200100000000 620 | 000000071930000000000000000000620400000030000070000000650007080200000900000108000 621 | 000000072000051000000000000000060180720300000400000000300200000000400600008000500 622 | 000000072006800000000000050170000300000400800020000000000217000309000000000050000 623 | 000000072010000000000060000000700510902000000400000000000510600300000009000807000 624 | 000000072080500000010000000200097000000000100300000000703000060000180500000400000 625 | 000000072080500000010000000200097000000000800600000000703000060000180500000400000 626 | 000000072080600000010000000400097000000000800300000000703000040000180600000500000 627 | 000000073200500000000000610003100000000900040800000700000086200010000000000030000 628 | 000000074002800000000000003070530000600000010000000200540000600000071000700000000 629 | 000000074010030000000000080000010520700600000400000000053000100000708000000000200 630 | 000000074010030000000000080000010520700600000400000000053000100000807000000000200 631 | 000000074150000000000000008010000230600048000000070000200500100000300000004000000 632 | 000000074200050000000000001000104030500000600008700000000390800010000000000000200 633 | 000000074500100000000000009800009500000040000000000010070200600000080300040700000 634 | 000000075320000000000000008010000240600058000000070000200400100000300000005000000 635 | 000000075400060000000000010002105000000700040600000300000390800010000000000000200 636 | 000000075400060000000000010002105000000700040900000300000390800010000000000000200 637 | 000000075400060000000000010003105000000700040600000300000390800010000000000000200 638 | 000000075400060000000000010003105000000700040900000300000390800010000000000000200 639 | 000000075620000000000000008010000240300058000000070000200400100000300000005000000 640 | 000000076060200000000000050000860400501000000700900000030005000900000200000010000 641 | 000000076400900000000000080008070000000200400090000300200000530000006001000080000 642 | 000000078500200000000000600067000050080000020000300400300000102000070000000006000 643 | 000000078500300000000000010400070200000018000030000000060400500000000430001000000 644 | 000000078600000050000040000058000000000001300040000000300600100000250000000700400 645 | 000000079030080000500000020080000560000209000000400000000030100200700000000000400 646 | 000000079030080000500000020080000560000209000000400000000040100200700000000000400 647 | 000000081000090030700004000000200600030800000010000000000010403500600000200000000 648 | 000000081000090040700005000000300600040800000010000000000010504300600000200000000 649 | 000000081000409000000200000060081000004000230000000000380070000200500900000000000 650 | 000000081000602000300700000604000700000090010700000000500400200010080000000000000 651 | 000000081020030000000000000000060320700450000100000000500708000060000200000100000 652 | 000000081020040000000700000000050620300090000100000000040300200500008000000100000 653 | 000000081020300000000000000109000040000200500800000000000580200070000300600010000 654 | 000000081020300000040006000000600420801050000000000700000400200500080000000000000 655 | 000000081020300000700000000040000700000018000000050000000600230500400000106000000 656 | 000000081020500000000000000400031000700000200060000000000260500103000040000700000 657 | 000000081020600000400000000090000200000038000000010000000500720300400000105000000 658 | 000000081020700000000000000000900250800000030400000700600018000050000300000040000 659 | 000000081020700000000403000100060050000200300500000000800010000040000700000050000 660 | 000000081020700000000403000100060050000200300500000000800010000070000400000050000 661 | 000000081020700000500000000060000200000038000000010000000600740200500000103000000 662 | 000000081020700000500000000090000400000038000000010000000600240300500000106000000 663 | 000000081030005000000000000500074600109000000000000000080000370600910000000200000 664 | 000000081030005000000000000500074600901000000000000000080000370600910000000200000 665 | 000000081030020000000700000000050620400090000100000000020400300500008000000100000 666 | 000000081030020000000700000000050620400090000100000000060400300500008000000100000 667 | 000000081030200000000000000108060040000700300600000000500300700090000200000010000 668 | 000000081030200000000000000108060040000900300600000000500300700070000200000010000 669 | 000000081030200000500000000000600230100400000700000000400070000000010800060000300 670 | 000000081030500000000020000100007000000080500050000400600100070000403000800000000 671 | 000000081030500000000020000100009000000080500050000400600100070000403000800000000 672 | 000000081030600000000020000500007000000080600060000400100500070000403000800000000 673 | 000000081030600000000020000700009000000080600060000400100500070000403000800000000 674 | 000000081040300000020006000000600420801050000000000700000400200500080000000000000 675 | 000000081050600000200009000000700300408000000100000000000010070030040000020000600 676 | 000000081060020000300000000050000260000107000000300000000430500701000000008000000 677 | 000000081060500000300000000500028000070000400000010000000600730002400000100000000 678 | 000000081060500000700000000200600500008000020100300000040021000050000600000000000 679 | 000000081060700000000200000040000600000083000000000020000502700308040000100000000 680 | 000000081070600000300000000400018000030000500000020000000500760002400000100000000 681 | 000000081070600000300000000400028000030000500000010000000500790002400000100000000 682 | 000000081080000020300000000016000000000500600090200000000091000500000300400080000 683 | 000000081090005000000000000070000630400810000000200000201060000000003500000000700 684 | 000000081090005000000000000070000630400810000000200000201060000000003700000000500 685 | 000000081090300000000200000708040000000600900100000300500080040030000600000000000 686 | 000000081100060000070050000009000760000102000000800400000300500800000020000000000 687 | 000000081200060000000000000048500000000020300010000000500000670000103000700400000 688 | 000000081200060000000700000000408070630000000000100000004000600000050200018000000 689 | 000000081200400000000000000000230700010000050008600000700000400090080000000050200 690 | 000000081200500000030000000020406000001000070000200000008010000000030200700000400 691 | 000000081200500000030000000020406000008000070000200000001080000000030200700000400 692 | 000000081200600000000000000089010050000403200000000600400000700000250000000080000 693 | 000000081200700000000000000000230700010000050008600000700000400030080000000050200 694 | 000000081200700000000000000000230700010000050008600000700000400040080000000050200 695 | 000000081200700000000000000000230700010000050008600000700000400090080000000050200 696 | 000000081200700000000500000000080650400010000500000700060300000089000000000000400 697 | 000000081200700000960000000000500630004200000800000000000081000050000900000040000 698 | 000000081230000000040700000000600370005300000100000000400000200000058000000010000 699 | 000000081250000000060700000000500670004200000100000000300000900000048000000010000 700 | 000000081300020000000700000048000000000060200010000000600000350700504000000100000 701 | 000000081300200000000074000200000560700010000000009000000800200014000000090000000 702 | 000000081300600000090400000680070000000300400000000020000012000500000300000080000 703 | 000000081360000000040700000500000300000021000000080000002000010000400600400300000 704 | 000000081400300000300050000190000500000028000000600000082000050000400700000000000 705 | 000000081400300000300050000190000500000028000000600000082000050000700400000000000 706 | 000000081400300000300050000190000500000082000000600000082000050000400700000000000 707 | 000000081400300000300050000190000500000082000000600000082000050000700400000000000 708 | 000000081400300000300050000610000500000082000000700000002000050000600400080000000 709 | 000000081400300000300050000680000500000012000000700000002000050000600400010000000 710 | 000000081500400000073000000000028000060000300000010000000600740200500000100000000 711 | 000000081600002000000700000500000360800100000000400000000060200047000000010030000 712 | 000000081600030000000200000020800000000040300000000500000102070304000600500000000 713 | 000000081600040000000230000400000050300700000000100000000050300010000200087000000 714 | 000000081600070000000000000000801040702000000300400000200000700000060300080500000 715 | 000000081600070000000000000000805040702000000300100000200000700000090300080500000 716 | 000000081600200000000000000010089000503000200000000600000300570240000000080000000 717 | 000000081600400000500700000012000000080090000000500000000010050030000600700000400 718 | 000000081600500000040000000502700030000600700080000000000013000900000600000080000 719 | 000000081690000000040300000508200000000000910070000000300000600000018000000070000 720 | 000000081700050000020000000601200000080000040000090300300004000200000500000800000 721 | 000000081700060000000000000400507000600000720000100000058200000000030200010000000 722 | 000000081700200000200000000000510030050040000600000800000700900003006000010000000 723 | 000000081700300000400050000610000500000082000000400000002000050000700400080000000 724 | 000000081700400000000200000400000300005010000000090000010350000200000640000000700 725 | 000000081700600000300500000000082000090010000500000000080040000000300700000000650 726 | 000000081700600000500000000040081000000000290000030000000504700600200000080000000 727 | 000000081900400000700600000082000000010050000000700000000080050030000900600000400 728 | 000000082000031000000000000080420000400000100000500000601000300000200050700000600 729 | 000000082000031000000000000080420000700000100000500000601000300000200050400000700 730 | 000000082005060000010000000090302000000100500800000040600040000300000001000000300 731 | 000000082040600000010000000200098000000000100300000000803000070000410600000500000 732 | 000000082500006000000000090600000300000920000000000040000053100090600000008000700 733 | 000000082500300000000000000300072000400000630000010000000800500081000000020000007 734 | 000000082600400000000000000400072000500000430000010000000800600081000000020000007 735 | 000000083000014000000200000000320000090000400000700000000006150308000000200000600 736 | 000000083000030010070000000000204000030000600000010000200600405000500700100000000 737 | 000000083020100000000000040000610200800000900004000000060300500100000070000008000 738 | 000000083020700000000000040000610200800000900004000000060300100500000070000008000 739 | 000000083040300000000500060300000400000700500208000000050060100000002000000080000 740 | 000000083400020000000000510002300000700000600000100040000075200010000000000800000 741 | 000000083500400000000100000000020700100000400000008000038600000020070000000000520 742 | 000000083900100000000000020100009700020080000000000100005700400003000060080000000 743 | 000000084000100000200000000000600130408000000050000000560000200000080007010030000 744 | 000000084000510000000030000400000200300008000000600070000200403076000000000000100 745 | 000000084050010000000000050000030620800200000400000000073000100000508000000000900 746 | 000000084100600000000000000000040103030020000500000600048000020000701500000000000 747 | 000000084600010000000000000500000106000800300070200000087000020000063500000000000 748 | 000000084750000000000000009010000730600049000000080000200500100000300000004000000 749 | 000000085004070000000000030100060700570000100030800000006200000000503000000000000 750 | 000000085200030000000000030040010600058000000000700000700400100000500200000008000 751 | 000000085760000000000000009010000640300059000000080000200400100000300000005000000 752 | 000000086320000000000000009010000250700069000000080000200500400000300000006000000 753 | 000000087004010000000000030100060500570000100030800000006200000000703000000000000 754 | 000000087004050000000000030100060500570000100030800000006200000000703000000000000 755 | 000000091000020000000400000507000200100900000860000000040000080090001000000070300 756 | 000000091000030000000500000608000300200900000170000000050000020090001000000080400 757 | 000000091002080000040700000050061400000090000300000000000300750900000000000200000 758 | 000000091020400000000000000000380200700090000000000400040500600900010070000200000 759 | 000000091020700000600000000080000500000039000000010000000600840300500000107000000 760 | 000000091030600000000020000700008000000090600060000400100500080000403000900000000 761 | 000000091060005000000000000080000630400910000000200000201070000000003500000000800 762 | 000000091060005000000000000080000630400910000000200000201070000000003800000000500 763 | 000000091060070000000000000005030760000000200100000000300100004082000000000409000 764 | 000000091060070000000000000005030760000000300100000000300100004082000000000409000 765 | 000000091070020000000004000000380000040000900000100000300000640000005700100800000 766 | 000000091070080000000000000006040870000000300100000000400100005032000000000509000 767 | 000000091080040000400000000000720500801000060900000000020000300000601000000900000 768 | 000000091080200000000000000930000800000014000000500000104000070000600200000380000 769 | 000000091080600000000030000000700260500400000100000000030050800000019000400000000 770 | 000000091080600000000030000000700280500400000100000000030050800000019000400000000 771 | 000000091200050000000000000500000240700800000060100000089400000000060300010000000 772 | 000000091200400000030000000060507000009000080000200000001090000000030200800000400 773 | 000000091200600000000000000040010600000039000070000200000400570300800000100000000 774 | 000000091200800000600000000040091000000000250000030000000604800700500000090000000 775 | 000000091300040000500600000007200600090000080000300000200000500000091000000080000 776 | 000000091300200000000085000600000270800040000000001000000600500049000000010000000 777 | 000000091400070000000000000700300000800000400000106000019500060000040700200000000 778 | 000000091400070000000000000700300000800000400000106000019500060000040800200000000 779 | 000000091400300000000000000000219000200000850000060000090000060000400700300000400 780 | 000000091400300000300050000710000500000092000000600000092000050000400800000000000 781 | 000000091400300000300050000790000500000012000000600000012000050000400800000000000 782 | 000000091500080000200000000000720600010300000090000000640100000000000520000000800 783 | 000000091500200000300000000080700040090000600000500000200060500010090000000003000 784 | 000000091600300000070000000400000500000029000000010000000500680310000000020800000 785 | 000000091600700000200000000700000010000600500000450000030081000040000600005000000 786 | 000000091600700000800000000040091000000000250000030000000604800200500000090000000 787 | 000000091600700000800000000040091000000000250000030000000604800700500000090000000 788 | 000000091603000000500000000090100040000002300700000000300000700000410000000980000 789 | 000000091630000000000000000019080000000020400000000600200600300000703050000400000 790 | 000000091630000000000000000051080000000020400000000600200600300000703050000400000 791 | 000000091630000000000000000091080000000020400000000600200600300000703050000400000 792 | 000000091700000030000200000090010080005000600200000000080090000000600400000700200 793 | 000000091700030000200500000600000200040900000000000000500008040090001000000020300 794 | 000000091700030000200500000600000200040900000000000000500008040090001000000060300 795 | 000000091700400000000030000000651000200000370000000000000800200054000000310000000 796 | 000000091700400000000380000000500800029000000010000000600002000000060010500000300 797 | 000000091700400000200000000500290000000080010040000600081000400000700300000000000 798 | 000000091700800000200000000000510030020040000600000900000700600003006000010000000 799 | 000000091700800000200000000000510030050040000600000900000700200003006000010000000 800 | 000000091700800000200000000000510030050040000600000900000700800003006000010000000 801 | 000000091700800000200000000000510030070040000600000900000700200003006000010000000 802 | 000000091700800000600000000040091000000000250000030000000604700200500000090000000 803 | 000000091800200000000400000060017030200000600000090000001050000000800200040000000 804 | 000000091800200000200000000000510030050040000600000900000700800003006000010000000 805 | 000000091800300000300050000470000500000092000000600000002000050000800400090000000 806 | 000000091800700000200000000000510030090040000600000900000200800003006000010000000 807 | 000000092010400000000000000030100400100060000000020007000500830209000000600000000 808 | 000000092700000010000300000090020080005000600300000000010090000000600400000700300 809 | 000000093000014000000200000000320000040000500000800000000007160309000000200000700 810 | 000000093480000000010000000503000060000010800000000000170000400000902000000300005 811 | 000000094000400070100000000208000600000750000000000100030060500047000000000002000 812 | 000000094030090000000000060070000820200600000000004000000750300906000000000000100 813 | 000000096200030000000000030050010700069000000000800000800400100000600200000009000 814 | 000000097000050000000040000107200000040000300000900000600701000030000450000000800 815 | 000000097300400000000000020600098100400007300000020000072000000000100000080000000 816 | 000000100000300000900000000700100600200000090000500000008020040010006005050090000 817 | 000000100000500000200000000035400000000010700080000200004000059600002000000070030 818 | 000000100000500000200000000035400000000010700080000200004000059600070000000002030 819 | 000000100000500000200000000035400000000010800070000200004000095600008000000020030 820 | 000000100000500000200000000035400000000010800070000200004000095600020000000008030 821 | 000000102000000340005080000360000000000090050010000000100403000007000600000100000 822 | 000000102000300500000608000000400030200050000100000000000070200080010000030000060 823 | 000000102000300500000708000000400070600050000100000000000040600070010000030000040 824 | 000000102000300600000408000000500040200060000100000000000070200050010000040000030 825 | 000000102000300600000709000000400030200050000100000000000080200040010000030000070 826 | 000000102000300600000809000000400080200050000100000000000070200080010000030000060 827 | 000000102000300700000409000000500040200060000100000000000080200090010000040000030 828 | 000000102000300700000809000000500080200060000100000000000010600080040000030000070 829 | 000000102030000400000700500080000030000015000000020000000300064201000000900000000 830 | 000000102040700000300500000008001000600000070000020000002000600000600300010070000 831 | 000000102080300000000000500000690080001000000500000000060000470000201000700050000 832 | 000000102400050000000000900060070080001000000000300000000001460320000050000900000 833 | 000000102500600000000000000023000700000405000010000300000170000000020080800000040 834 | 000000102700050000000000800060070040001000000000300000000001460320000050000800000 835 | 000000102700050000000000900060070080001000000000300000000001460320000050000900000 836 | 000000102700400000000000800300000640400009000000010000012600000000500030090000000 837 | 000000102900050000000000800040060070001000000000300000000001460320000050000800000 838 | 000000102900050000000000800060070040001000000000300000000001460320000050000800000 839 | 000000103000400500670000000000020070300000000001000000000063400007500000020000080 840 | 000000103020090000000000400000025080010000000400000000300104000008000020000700600 841 | 000000103020400000000670000070000400000001000000000070000240060301000500800000000 842 | 000000103080020000000004500030000020000500070000100000100300600700080000005000000 843 | 000000103800050000000000700060020040001000000000300000000001460420000050000700000 844 | 000000103800600000200000700000406080010000000000700000008003000030010000400050000 845 | 000000103900050000000000700060020040001000000000300000000001460820000050000700000 846 | 000000103900050000000000800060020070001000000000300000000001460720000050000800000 847 | 000000104000003600000050002503000000200600000000100080000070230010000000000400000 848 | 000000104000010800600700000391000000080500000000200000506000070400080000000000000 849 | 000000104000060000000050000200430000000107000600000800010500000070000040000000023 850 | 000000104000080300040050000000200070300000600001004000870000050000300000000100000 851 | 000000104000702000000000000460010000000500070100000000000380600027000030004000000 852 | 000000104000802000000000000460070000000600080100000000000340700028000050009000000 853 | 000000104080900000000000500000702080001000000500000000000530600020000030400010000 854 | 000000104702000000000000000000705020300600000010000000200000630050014000000080000 855 | 000000104800070000000000600700200000000104000030000080012000000000050030604000000 856 | 000000104800090000000000600700200000000401000030000090012000000000050030604000000 857 | 000000105000700400700200000000500080403000000061000000500000020040060000000010000 858 | 000000105002000600030800000100000400000308000000200000570000030400060000000010000 859 | 000000105002600000000902000300000090000070800000010000710000500000200040080000000 860 | 000000105004070000000000300150300000000600080020000000000051200006000070800000000 861 | 000000105030800000000000000000012000060000030000000700102000400500360000000700080 862 | 000000105030800000000000600020030000500006000000000270601000004000200030000070000 863 | 000000105200007000000030600009000400010500000000002030300000070000980000000100000 864 | 000000105200800000000000300000071000000004800300050000000300026004000050010000000 865 | 000000105300040000000000000000080720905600000000000040020000800000100030000509000 866 | 000000105302000000000000000000206030710000000000300000400000820070015000000090000 867 | 000000105802000000000000000000406030200300000010000000400000720060015000000090000 868 | 000000105802000000000000000000406030400700000010000000300000720060015000000090000 869 | 000000105802000000000000000000806020300700000010000000400000730060015000000090000 870 | 000000105802000000000000000000806020400700000010000000200000730060015000000090000 871 | 000000105802000000000000000000806030300700000010000000400000720060015000000090000 872 | 000000106000025000300000000009100400000400000000000020520000080000630700000007000 873 | 000000106020000500000082000010000200000040030000500000703000040400600000000001000 874 | 000000106020070000800000500097000030000500040000100000000020780100600000000000000 875 | 000000106020070000900000500078000030000500040000100000000020780100600000000000000 876 | 000000106030070000400000500078000020000500040000100000000020780100600000000000000 877 | 000000106030070000900000500078000020000500040000100000000020780100600000000000000 878 | 000000106040700000000500300070000450600010000000000000000450020300000080100000000 879 | 000000106040800000000500300070000450600010000000000000000480020300000090100000000 880 | 000000106200005000000000800320000070000010000000800000071000400000023050000600000 881 | 000000106302000000000000000000207030400800000010000000500000840070016000000090000 882 | 000000106302000000000000000000507030500800000010000000200000840070016000000090000 883 | 000000106390000000000000500000610200870000000000500000000407030001050000000000080 884 | 000000106402000000000000000000207030500800000010000000300000840070016000000090000 885 | 000000106402000000000000000000507030500800000010000000200000840070016000000090000 886 | 000000106402000000000000000000507030500800000010000000300000840070016000000090000 887 | 000000107000001300800040000500300000006000040200000000000200050010000200030700000 888 | 000000107000001300800050000200300000006000050400000000000200040010000200030700000 889 | 000000107000025000300000000004100600000400000000000020520000090000730800000008000 890 | 000000107000500300000602000800000026600000040000010000410000700000200000030000000 891 | 000000107000800300800200000000700090403000000061000000500000020090060000000010000 892 | 000000107000800400200300000000700090504000000061000000300000020090060000000010000 893 | 000000107000800400800300000000700090504000000061000000300000020090060000000010000 894 | 000000107000902000000500600900000850000010000400000000007400020010000030060000000 895 | 000000107020030000000000600000040020700600000100000000040200050008000300000105000 896 | 000000107024000000000500600030000050000100400900000000000039020700000008001000000 897 | 000000107040080000900000600028000030000600050000100000000020890100700000000000000 898 | 000000107040080000900000600082000030000600050000100000000020890100700000000000000 899 | 000000107090020000000000004000401500020003060000700000000090030400800000100000000 900 | 000000107400200000080300000200000480000076000000000000567000000000400030001000000 901 | 000000107400200000100000000098000050070000006000100000000095300000070400000000020 902 | 000000107830000000000060400600200050000107000000000000071400000000050680000000000 903 | 000000107900020000000000800000701500400000030000900000000340060008000020010000000 904 | 000000108000008300700040000500300000006000040200000000000200050080000200030100000 905 | 000000108000008300700050000200300000006000050400000000000200040080000200030100000 906 | 000000108000407000000500300040000620000010000020000000701000050000200070300000000 907 | 000000108000600400200300000000800090504000000071000000600000020090070000000010000 908 | 000000108000605000000400300040000620000010000020000000106000050000200070300000000 909 | 000000108009400000000300700600000040000020000000010000370005000010000200000600080 910 | 000000108040200000000600000020400030700010500000000000100080000000000340000000026 911 | 000000108050400000000200000020500030700010600000000000100080000000000350000000042 912 | 000000108200300000600000000010054000000000020000008000000230040080000500700600000 913 | 000000108200700000000000300500000090000038000020010000010000400000500020007600000 914 | 000000108300060000000000500900000600000800020000401000085000001000030070040000000 915 | 000000108400200000100000000089000050070000006000100000000075300000080400000000020 916 | 000000108500040000000000700030050020001000000000200000000001360820000040000700000 917 | 000000108500200000000000400900000050000340000000060200000605070041000000000000030 918 | 000000108600200000000000400200000050000340000000070300000605020041000000000000030 919 | 000000108600300000200000000010058000000000020000001000000230040080000900700600000 920 | 000000108700400000000000000000038600400000070000010000000500064035200000010000000 921 | 000000108900040000000000700030050060001000000000200000000001350820000040000700000 922 | 000000108900040000000000700050060030001000000000200000000001350820000040000700000 923 | 000000109000200300040070000070000080000300000000100000203000600000004050100080000 924 | 000000109000400200000508000000300080100000040200000000060000730430000000000010000 925 | 000000109000807000000500300040000620000010000080000000701000050000400070300000000 926 | 000000109040200000030000400600405020100000000000700000000000870000019000000060000 927 | 000000109200600000000050400000010500000700030300000000000802060014000000000000070 928 | 000000109300400000000000200027006000000800500009000000510020000400000030000090000 929 | 000000109400050000000020300000109000500007000000300000013000000080000040009000020 930 | 000000109400050000090020000000401700060000000000700000000060020700300000801000000 931 | 000000109700008000000000000360000080010590000000000020000140600205000000000900000 932 | 000000109700400000000000000000039600400000070000010000000500084035200000010000000 933 | 000000120000040700030007000057000008000410000000200000000000053400600000100000000 934 | 000000120063000000000000000040000503100208000000700000500000080002600000000030400 935 | 000000126000850000000000004000300700400001000105000000070000380000046000000000000 936 | 000000126000950000000000004000300800400001000105000000030000790000046000000000000 937 | 000000130000080005420000000600000020005010000000000400070402000000600200000000001 938 | 000000130020400000000000000000600025700080000100000000000016700005200000040000300 939 | 000000130040020000000000000000000026700900000100000000062050004000107300000800000 940 | 000000130047000000050000000100302000000050007000000040800000200000603000000740000 941 | 000000130200600000700500000040010300000200050010000000500000007000084000000030000 942 | 000000130400070000800000000000506200700300004000100000000080076015000000000000000 943 | 000000130800600000200500000040010300000200050010000000500000008000074000000030000 944 | 000000135608000000000000040030400010000027000050000000200000706000000200000300000 945 | 000000135608000000000000040050400010000076000030000000200000706000000200000300000 946 | 000000135807000000000000040030400010000076000050000000200000706000000200000300000 947 | 000000136087000000000000050000740900360000000000000000004080200600305000000000000 948 | 000000140090020000000000000000107400950000000000400000001000302000090050800600000 949 | 000000140090020000000600700401000000000580000300000000080000502000001030000400000 950 | 000000140400000600000500000000305008200700000106000000050000083600010000000000000 951 | 000000150080020000000000000000501400870000000000400000001000320000080007500600000 952 | 000000150900700000000000030042000700001030000050000000200600800300400000000050000 953 | 000000160000009500000040000041020000000300600080000000700000024300900000000000008 954 | 000000160020700000000000900600010000000040002030000000100000470000300005800200000 955 | 000000160040020000000009070300100000000000402600000000000630500029000000000800000 956 | 000000160200040000000000708000530020007000050010000000300006400000107000000000000 957 | 000000160200070000300000800000608900420000000000500000000010002008000050060000000 958 | 000000160200070000300000800000608900420000000000500000000040002008000050060000000 959 | 000000160800400000000000700000070600010030000200000050000208000076000000000500004 960 | 000000170000004600000050000051020000000300700080000000700000025400900000000000008 961 | 000000170020900000000000600600010000000040002030000000100000460000300005800200000 962 | 000000170030040000000000600600100000000006030005000004000650200740000000000800000 963 | 000000170040800000000000002000500048200070000100000000000010260080600000000000300 964 | 000000175049600000000000000500000300100090000000420000020000049300001000000000000 965 | 000000180000205000000003000010080000000600002003000000000040710600000300200500000 966 | 000000180300500000000000020061000000000300400008000000710000300000086005000020000 967 | 000000180300900000000000020068000000000300400001000000710000300000086005000020000 968 | 000000190300400000000000020071000000000300500009000000810000400000097006000020000 969 | 000000201000020500080004000000230000090000040000500000602100000500000300000000070 970 | 000000201000080400300050000000204000500000070000600000004100002020000600000000030 971 | 000000201000370000000000000430010000000002600080000070000800530001000020700000000 972 | 000000201004030000000000000370000080600200000000500000540000600000070040002001000 973 | 000000201005090000038000000120400000000030080700000000000000430000201000000600000 974 | 000000201005090000038000000120400000000030080700000000000000530000201000000600000 975 | 000000201009050000400700000600102000000000030000800000000040690710000000000030000 976 | 000000201030070000000400800000050040801000000006000000200801000050000700000000090 977 | 000000201040030000000006000600072000030000040000100500201800000000000730000000000 978 | 000000201060400000003000000200070100500020000000000060100000500000308000000600040 979 | 000000201070300000000000000060000030000205000000041000005780060100000400200000000 980 | 000000201080050000000000000600201000000500740000300000000084050302000000100000000 981 | 000000201080300000000000000060000030000205000000041000005780060100000400200000000 982 | 000000201080400000000700000000540080302000000100000000500032600070000040000000000 983 | 000000201090004000030000000000008530700000400100000000200670000000020800000100000 984 | 000000201090030000000000004006000530300400000000100000000090080204000000170000000 985 | 000000201090400000000300000170020000000008600000000050208000500000900040006000000 986 | 000000201096000000000000500000090040200030000100000000070502000000006083000100000 987 | 000000201500300000000070000000500030020004000076000000000000350000021000800000400 988 | 000000201600300000700000000008540000020000030000600700010082000500000060000000000 989 | 000000201730000000600040000000060030008000500200000000001200000000508000060000070 990 | 000000201800000900000400000000610030270000000900000000090072000001000040000800000 991 | 000000203006400000000000500100600070820000000000830000000059000050002000000000040 992 | 000000203010700000000000000000023400090060000800000000000800019600900070200000000 993 | 000000203080700000000000100005000040300010000000000600000407060100000080200500000 994 | 000000203800600000000000700002000100040800000000300060000027040300000005000010000 995 | 000000204000001000000080000020400500000030700000000080100200006806000010000700000 996 | 000000204001000000050000000006500080200009000000000010000150700940000300000800000 997 | 000000204050030000000000690000850010206000000900000000000206000130000000000400000 998 | 000000204050700000680000000300000090000014000000020000201000000000800050000600700 999 | 000000204100900000000000007670300000000100830040000000000025000500000090000040000 1000 | 000000204100900000000000008680700000000100730040000000000025000500000090000040000 1001 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/test_group: -------------------------------------------------------------------------------- 1 | ./test1 2 | ./test1000 3 | ./test1000 4 | ./test10000 5 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku/threadpool.cc: -------------------------------------------------------------------------------- 1 | #include "threadpool.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace mythreadpool; 10 | 11 | void ThreadPool::start(int numThreads) 12 | { 13 | //assert(threads_.empty()); 14 | running = true; 15 | mythreads.reserve(numThreads);//更改vector的容量,为最大线程个数 16 | for (int i = 0; i < numThreads; ++i)//循环创建线程 17 | { 18 | pthread_create (&mythreads[i], NULL,runInThread,NULL); 19 | } 20 | 21 | } 22 | 23 | /*销毁线程池,等待队列中的任务不会再被执行,但是正在运行的线程会一直 24 | 把任务运行完后再退出*/ 25 | void ThreadPool::stop() 26 | { 27 | 28 | if (!running)return ;/*防止两次调用*/ 29 | 30 | /*唤醒所有等待线程,线程池要销毁了*/ 31 | pthread_mutex_lock(&_mutex); 32 | running=false; 33 | void * thread_result; 34 | 35 | pthread_cond_broadcast (¬empty); 36 | pthread_cond_broadcast (¬full); 37 | pthread_mutex_unlock(&_mutex); 38 | 39 | //阻塞主线程,等待其它线程执行结束 40 | for (int i = 0; i < mythreads.size(); ++i){ 41 | pthread_join (mythreads[i], &thread_result); 42 | //输出获取到的线程的返回值 43 | printf("%s\n", (char*)thread_result); 44 | } 45 | /*销毁等待队列*/ 46 | mythreads.clear(); 47 | /*条件变量和互斥量也别忘了销毁*/ 48 | pthread_mutex_destroy(&_mutex); 49 | pthread_cond_destroy(¬full); 50 | pthread_cond_destroy(¬empty); 51 | 52 | } 53 | 54 | 55 | int ThreadPool::queueSize() 56 | { 57 | pthread_mutex_lock(&_mutex); 58 | return myqueue.size(); 59 | pthread_mutex_unlock(&_mutex); 60 | } 61 | 62 | void ThreadPool::run(Task task) 63 | { 64 | if (mythreads.empty())//如果线程池当中的线程是空的 65 | { 66 | task();//那么就直接执行任务,不进行在线程池中添加任务 67 | } 68 | else 69 | { 70 | pthread_mutex_lock(&_mutex); 71 | 72 | while (isFull()&&running) 73 | { 74 | pthread_cond_wait (¬full, &_mutex); 75 | } 76 | if (!running) return; 77 | myqueue.push_back(std::move(task));//在任务队列中添加任务 78 | pthread_cond_signal(¬empty); 79 | pthread_mutex_unlock(&_mutex); 80 | 81 | } 82 | } 83 | 84 | ThreadPool::Task ThreadPool::take() 85 | { 86 | pthread_mutex_lock(&_mutex); 87 | while (myqueue.empty() && running)//如果任务队列中的任务是空的,且处于运行状态 88 | { 89 | pthread_cond_wait (¬empty, &_mutex);//需要等待任务 90 | 91 | 92 | } 93 | //否则说明有任务 94 | Task task; 95 | if (!myqueue.empty()) 96 | { 97 | task = myqueue.front();//取出任务,queue,先进先出 98 | myqueue.pop_front();//删除任务 99 | if (maxq > 0) 100 | { 101 | pthread_cond_signal(¬full); 102 | } 103 | } 104 | pthread_mutex_unlock(&_mutex); 105 | return task; 106 | } 107 | 108 | 109 | 110 | 111 | void* ThreadPool::runInThread(void *arg) 112 | { 113 | while (running)//如果线程队列在运行 114 | { 115 | Task task(take());//取出一个任务 116 | if (task) 117 | { 118 | task(); 119 | } 120 | 121 | } -------------------------------------------------------------------------------- /Lab1/src/Sudoku/threadpool.h: -------------------------------------------------------------------------------- 1 | #ifndef THREADPOOL_H 2 | #define THREADPOOL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | using namespace std; 17 | namespace mythreadpool 18 | { 19 | /*线程池结构*/ 20 | class ThreadPool 21 | { 22 | public: 23 | 24 | //explicit禁止编译器执行非预期 (往往也不被期望) 的类型转换 25 | explicit ThreadPool(string name ){ 26 | myname=name; 27 | running=false; 28 | maxq=0; 29 | 30 | pthread_mutex_init (&_mutex, NULL); 31 | pthread_cond_init (¬full, NULL); 32 | pthread_cond_init (¬empty, NULL); 33 | 34 | } 35 | ~ThreadPool(){ 36 | if (running){ 37 | stop(); 38 | } 39 | } 40 | 41 | typedef std::function Task; 42 | 43 | 44 | void start(int numThreads); 45 | void stop(); 46 | void run(Task t); //运行任务,往线程池中的任务队列添加任务 47 | bool isFull() { 48 | return maxq <= myqueue.size(); 49 | } 50 | 51 | 52 | void setqSize(int num) { maxq = num; } 53 | std::string name() { return myname; } 54 | int queueSize(); 55 | 56 | bool running;//线程池是否运行 57 | int shutdown; 58 | int cur_queue_size; 59 | 60 | 61 | private: 62 | 63 | 64 | Task take();//获取任务函数 65 | static void* runInThread(void *arg); 66 | 67 | pthread_mutex_t _mutex;//条件变量使用锁 68 | pthread_cond_t notfull;//线程池非满条件变量 69 | pthread_cond_t notempty;//线程池非空条件变量 70 | 71 | string myname; 72 | Task threadtask; 73 | std::vector mythreads; 74 | std::deque myqueue; 75 | 76 | // 任务队列的最大大小 77 | int maxq; 78 | 79 | }; 80 | } 81 | #endif 82 | -------------------------------------------------------------------------------- /Lab1/src/Sudoku_answer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/Sudoku_answer.png -------------------------------------------------------------------------------- /Lab1/src/Sudoku_puzzle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/Sudoku_puzzle.png -------------------------------------------------------------------------------- /Lab1/src/Wrong_Example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/Wrong_Example.png -------------------------------------------------------------------------------- /Lab1/src/answer_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/answer_group.png -------------------------------------------------------------------------------- /Lab1/src/test_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/test_group.png -------------------------------------------------------------------------------- /Lab1/src/where_ext4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/where_ext4.png -------------------------------------------------------------------------------- /Lab1/src/图2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/图2-1.png -------------------------------------------------------------------------------- /Lab1/src/图2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/图2-2.png -------------------------------------------------------------------------------- /Lab1/src/图2-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab1/src/图2-3.png -------------------------------------------------------------------------------- /Lab2/README.md: -------------------------------------------------------------------------------- 1 | # Lab2: Your Own HTTP Server 2 | 3 | *Some materials are from Homework 2 of CS162 2019 at UC Berkeley.* *Thanks to CS162!* 4 | 5 | Enter in the folder you have cloned from our lab git repo, and pull the latest commit. 6 | 7 | `git pull` 8 | 9 | You can find this lab2's instruction in `Lab2/README.md` 10 | 11 | All materials of lab2 are in folder `Lab2/` 12 | 13 | ## 1. Overview 14 | 15 | Implement an HTTP server based on HTTP/1.1 from scratch by your own, using network programming knowledges learned from our class. Also, try to use high concurrency programming skills learned from the class to guarantee the web server's performance. 16 | 17 | ### Goals 18 | 19 | * Practice basic network programming skills, such as using socket API, parsing packets; 20 | * Get familiar with robust and high-performance concurrent programming. 21 | 22 | ## 2. Background 23 | 24 | ### 2.1 Hypertext Transport Protocol 25 | 26 | The Hypertext Transport Protocol (HTTP) is the most commonly used application protocol on the Internet today. Like many network protocols, HTTP uses a client-server model. An HTTP client opens a network connection to an HTTP server and sends an HTTP request message. Then, the server replies with an HTTP response message, which usually contains some resource (file, text, binary data) that was requested by the client. We briefly introduce the HTTP message format and structure in this section for your convenience. Detailed specification of HTTP/1.1 can be found in [RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1](https://tools.ietf.org/html/rfc2616). 27 | 28 | ### 2.2 HTTP Messages 29 | 30 | HTTP messages are simple, formatted blocks of data. All HTTP messages fall into two types: **request** messages and **response** messages. Request messages request an action from a web server. Response messages carry results of a request back to a client. Both request and response messages have the same basic message structure. 31 | 32 | #### 2.2.1 Message Format 33 | 34 | HTTP request and response messages consist of 3 components: 35 | 36 | - a start line describing the message, 37 | - a block of headers containing attributes, 38 | - and an optional body containing data. 39 | 40 | Each component has the format as following 41 | 42 | ##### 2.2.1.1 Start Line 43 | 44 | All HTTP messages begin with a start line. The start line for a request message says *what to do*. The start line for a response message says *what happened*. 45 | 46 | Specifically, the start line is also called ***Request line*** in *Request messages* and ***Response line*** in *Response messages*. 47 | 48 | 1. **Request line:** The request line contains a method describing what operation the server should perform and a request URL describing the resource on which to perform the method. The request line also includes an HTTP version tells the server what dialect of HTTP the client is speaking. All of these fields are separated by whitespace. 49 | 50 | Example of request line: 51 | 52 | `GET /index.html HTTP/1.1` 53 | 54 | 2. **Response line:** The response line contains the HTTP version that the response message is using, a numeric status code, and a textual reason phrase describing the status of the operation. 55 | 56 | Example of response line: 57 | 58 | `HTTP/1.1 200 OK` 59 | 60 | ##### 2.2.1.2 Header 61 | 62 | Following the start line comes a list of zero, one, or many HTTP header fields. HTTP header fields add additional information to request and response messages. They are basically just lists of name/value pairs. Each HTTP header has a simple syntax: a name, followed by a colon (:), followed by optional whitespace, followed by the field value, followed by a CRLF. 63 | 64 | HTTP headers are classified into: General headers, Request headers, Response headers, Entity headers and Extension headers. Note that request-header fields are different from the response-header fields. We will not introduce those fields in details and you are not required to implement in this lab. You can find them in [RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1](https://tools.ietf.org/html/rfc2616). 65 | 66 | Example of headers in a request: 67 | 68 | ``` 69 | Host: 127.0.0.1:8888 70 | User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0 71 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 72 | Accept-Language: en-US,en;q=0.5 73 | Accept-Encoding: gzip, deflate 74 | Connection: keep-alive 75 | Upgrade-Insecure-Requests: 1 76 | Cache-Control: max-age=0 77 | // CRLF 78 | ``` 79 | 80 | Example of headers in a response: 81 | 82 | ``` 83 | Server: Guo's Web Server 84 | Content-length: 248 85 | Content-type: text/html 86 | // CRLF 87 | ``` 88 | 89 | ##### 2.2.1.3 Entity Body 90 | 91 | The third part of an HTTP message is the optional entity body. Entity bodies are the payload of HTTP messages. They are the things that HTTP was designed to transmit. 92 | 93 | HTTP messages can carry many kinds of digital data: images, video, HTML documents, software applications, credit card transactions, electronic mail, and so on. 94 | 95 | Example of entity body: 96 | 97 | ``` 98 | 99 | CS06142 100 | 101 |

CS06142

102 |

Welcome to Cloud Computing Course.
103 |

104 |
105 |
Http Server at ip-127-0-0-1 Port 8888
106 | 107 | ``` 108 | 109 | #### 2.2.2 Structure of HTTP Request 110 | 111 | A HTTP request message contains an HTTP request line (containing a method, a query string, and the HTTP protocol version), zero or more HTTP header lines and a blank line (i.e. a CRLF). 112 | 113 | Example of HTTP request message: 114 | 115 | ``` 116 | GET /index.html HTTP/1.1 117 | Host: 127.0.0.1:8888 118 | User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0 119 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 120 | Accept-Language: en-US,en;q=0.5 121 | Accept-Encoding: gzip, deflate 122 | Connection: keep-alive 123 | Upgrade-Insecure-Requests: 1 124 | Cache-Control: max-age=0 125 | // CRLF 126 | ``` 127 | 128 | #### 2.2.3 Structure of HTTP Response 129 | 130 | A HTTP response message contains an HTTP response status line (containing the HTTP protocol version, the status code, and a description of the status code), zero or more HTTP header lines, a blank line (i.e. a CRLF by itself) and the content requested by the HTTP request. 131 | 132 | Example of HTTP response message: 133 | 134 | ``` 135 | HTTP/1.1 200 OK 136 | Server: Tiny Web Server 137 | Content-length: 248 138 | Content-type: text/html 139 | // CRLF 140 | 141 | CS06142 142 | 143 |

CS06142

144 |

Welcome to Cloud Computing Course.
145 |

146 |
147 |
Http Server at ip-127-0-0-1 Port 8888
148 | 149 | ``` 150 | 151 | ### 2.3 HTTP Proxy 152 | 153 | HTTP proxy servers are intermediaries. Proxies sit between clients and servers and act as "middlemen", shuffling HTTP messages back and forth between the parties. 154 | 155 | HTTP proxy servers are middlemen that fulfill transactions on the client's behalf. Without a HTTP proxy, HTTP clients talk directly to HTTP servers. With a HTTP proxy, the client instead talks to the proxy, which itself communicates with the server on the client's behalf. 156 | 157 | HTTP proxy servers are both web servers and web clients. Because HTTP clients send request messages to proxies, the proxy server must properly handle the requests and the connections and return responses, just like a web server. At the same time, the proxy itself sends requests to servers, so it must also behave like a correct HTTP client, sending requests and receiving responses. 158 | 159 | The working pattern of HTTP proxy is shown in the following figure: 160 | 161 | ``` 162 | +-----------+ +-----------+ 163 | | | | | 164 | +----------+ Request | | Request | | 165 | | |+---------------> |+--------------> | 166 | | Client | | Proxy | | Server | 167 | | <---------------+| <--------------+| | 168 | +----------+ Response | | Response | | 169 | | | | | 170 | +-----------+ +-----------+ 171 | ``` 172 | 173 | ## 3. Your Lab Task 174 | 175 | ### 3.1 Implement your own HTTP Server 176 | 177 | In this Lab, we won't provide any basic code. So, you should implement a HTTP server (base on HTTP/1.1) from scratch which satisfies the following requirements: 178 | 179 | #### 3.1.1 HTTP Server Outline 180 | 181 | From a network standpoint, your HTTP server should implement the following: 182 | 183 | 1. Create a listening socket and bind it to a port 184 | 2. Wait a client to connect to the port 185 | 3. Accept the client and obtain a new connection socket 186 | 4. Read in and parse the HTTP request 187 | 5. Start delivering services: 1) Handle HTTP GET/POST request and return an error message if an error occur. 2) Proxy the request to another HTTP server (optional for advanced version). 188 | 189 | The server will be in either non-proxy mode or proxy mode (we have introduced the proxy in section `2.3`). It does not do both things at the same time. 190 | 191 | #### 3.1.2 Handle HTTP request 192 | 193 | In this Lab, **you just need to implement the GET method and the POST method in your HTTP server**. That is to say, if your HTTP server receive a HTTP request but the request method is neither GET nor POST. The HTTP server just need to return a 501 Not Implemented error message (a response message with Response line having status code to be 501, see `2.2`). 194 | 195 | There is no need to handle the header line(s) in the request (but you need to recognize it so that you will not mix it with the next request's start line). Also, you are free to fill any (or zero) header line(s) in the HTTP response. 196 | 197 | ##### 3.1.2.1 Handle HTTP GET request 198 | 199 | The HTTP server should be able to handle HTTP GET requests for html pages. 200 | 201 | 1. If the HTTP request’s path corresponds to a html page file, respond with a 200 OK and the full contents of the file. For example, if GET /index.html is requested, and a file named index.html exists in the files directory. You should also be able to handle requests to files in subdirectories of the files directory (e.g. GET /images/hero.jpg). 202 | 2. If the HTTP request’s path corresponds to a directory and the directory contains an `index.html` file, respond with a 200 OK and the full contents of the index.html file in that folder. 203 | 3. If the requested page file does not exist, or the requested directory does not contain an `index.html` file, return a 404 Not Found response (the HTTP body is optional). 204 | 205 | See examples in section `3.1.7.1`. 206 | 207 | 208 | ##### 3.1.2.2 Handle HTTP POST request 209 | 210 | The HTTP server should be able to handle HTTP POST requests. In this lab, the way of handle HTTP POST is very simple. 211 | 212 | 1. You should construct an HTTP POST request (see section `3.1.7.2`) that contains 2 keys: "Name" and "ID" (please fill in your name and student number respectively), and send the POST request to `/Post_show` (i.e. `http://127.0.0.1:8888/Post_show` if server's IP is `127.0.0.1` and service port is `8888`). 213 | 214 | Then, if the HTTP server receive this POST request (the request URL is `/Post_show` and the keys are "Name" and "ID"), respond with a 200 OK and echo the "Name"-"ID" pairs you have sent. 215 | 216 | 2. Otherwise (i.e. the request URL is not `/Post_show` or the keys are not "Name" and "ID"), return a 404 Not Found response message. 217 | 218 | See examples in section `3.1.7.2`. 219 | 220 | ##### 3.1.2.3 Other request 221 | 222 | Just return 501 Not Implemented error message for other request method (e.g. DELETE, PUT, etc.). 223 | 224 | See examples in section `3.1.7.3`. 225 | 226 | #### 3.1.3 Implement a proxy server (optional) 227 | 228 | Enable your server to proxy HTTP requests to another HTTP server and forward the responses to the clients. 229 | 230 | 1. You should use the value of the `--proxy` command line argument, which contains the address and port number of the upstream HTTP server. 231 | 2. Your proxy server should wait for new data on both sockets (the HTTP client fd, and the upstream HTTP server fd). When data arrives, you should immediately read it to a buffer and then write it to the other socket. You are essentially maintaining 2-way communication between the HTTP client and the upstream HTTP server. Note that your proxy must support multiple requests/responses. 232 | 3. If either of the sockets closes, communication cannot continue, so you should close the other socket and exit the child process. 233 | 234 | Hints: 1) This is more tricky than writing to a file or reading from stdin, since you do not know which side of the 2-way stream will write data first, or whether they will write more data after receiving a response. 2) You should again use threads for this task. For example, consider using two threads to facilitate the two-way communication, one from A to B and the other from B to A. 235 | 236 | #### 3.1.4 Use multi-thread to increase concurrency 237 | 238 | Your HTTP server should use multiple threads to handle as many concurrent clients' requests as possible. You have at least the following three options to architect your multi-thread server: 239 | 240 | - **On-demand threads**. You can can create a new thread whenever a new client comes in, and use that thread to handle all that clients' task, including parsing the HTTP request, fetching page files, and sending response. The thread can be destroyed after that client finishes, e.g, detect through TCP `recv()`. However,it may not be easy to detect client finish in the HTTP layer. 241 | - **A pool of always-on threads**. You can use a fixed-sized thread pool in your HTTP server program for handling multiple client requests concurrently. If there are no tasks, those threads are in a waiting state. If a new client comes in, assign a thread to handle the client's request and send response to it. If the assigned thread is busy, you can use a work queue to buffer the request, and let the thread process it later. 242 | - **Combined**. Combine above two styles together. For example, you can use thread pool to receive request and send response, and use on-demand threads to fetch large page files. 243 | 244 | Feel free to choose any one from the above three, or use other multi-thread architecture that you think is cool. 245 | 246 | #### 3.1.5 Specify arguments 247 | 248 | Your program should enable long options to accept arguments and specify those arguments during start. They are `--ip`, `--port`, and `--proxy` (optional). 249 | 250 | 1. `--ip`             —— Specify the server IP address. 251 | 2. `--port`           —— Selects which port the HTTP server listens on for incoming connections. 252 | 4. `--proxy`         —— Selects an “upstream” HTTP server to proxy. The argument can have a port number after a colon (e.g. `https://www.CS06142.com:80`). If a port number is not specified, port 80 is the default. 253 | 254 | If you have no idea about *long options*, you can read [this](https://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html#Argument-Syntax). And you may need to use some functions like `getopt_long()`, `getopt_long_only()`, `getopt()` and so on. Check those function's usage with the `man` command. 255 | 256 | #### 3.1.6 Run your HTTP Server 257 | 258 | Your program should be able to start at terminal. If your program is called *httpserver*, just typing: 259 | 260 | in the non-proxy mode: 261 | 262 | `./httpserver --ip 127.0.0.1 --port 8888 --number-thread 8` 263 | 264 | It means that your HTTP server's IP address is 127.0.0.1 and service port is 8888. The --number-thread indicates that there are 8 threads in the thread pool for handling multiple client request concurrently. 265 | 266 | in the proxy mode: 267 | 268 | `./httpserver --ip 127.0.0.1 --port 8888 --number-thread 8 --proxy https://www.CS06142.com:80` 269 | 270 | It means that this is an HTTP proxy. This proxy's IP address is 127.0.0.1 and service port is 8888. And the proxy has a thread pool with 8 threads. The --proxy indicates that the "upstream" HTTP server is `https://www.CS06142.COM:80`. So, if you send a request message to this proxy (i.e. `127.0.0.1:8888`), it will forward this request message to the "upstream" HTTP server (i.e. `https://www.CS06142.com:80`) and forward the response message to the client. 271 | 272 | When you run the command above, your HTTP server should run correctly. 273 | 274 | #### 3.1.7 Accessing Your HTTP Server 275 | 276 | ##### 3.1.7.1 Using GET method 277 | 278 | 1. You can check that your HTTP server works by opening your web browser and going to the appropriate URL. [Note] IP 127.0.0.1 refers to the IP of local host. So you can use 127.0.0.1 to test your HTTP server on the same local machine. 279 | 280 | For example: 281 | 282 | index page 283 | 284 | You can also send HTTP requests with the curl program. An example of how to use curl is: 285 | 286 | `curl -i -X GET http://127.0.0.1:8888/index.html` 287 | 288 | For example: 289 | 290 | index page curl 291 | 292 | 2. If the request page does not exist, your HTTP server should return a 404 Not Found error message. 293 | 294 | For example: 295 | 296 | not found page curl 297 | 298 | ##### 3.1.7.2 Using POST method 299 | 300 | 1. You can check whether the POST method works by sending a HTTP request with the curl program. Typing the command at terminal: 301 | 302 | `curl -i -X POST --data 'Name=HNU&ID=CS06142' http://127.0.0.1:8888/Post_show` 303 | 304 | For example: 305 | 306 | post curl 307 | 308 | You can also construct a POST HTTP request and send the request to HTTP server using some browser plug-in tools. 309 | 310 | 2. If the request URL is not `/Post_show` or the keys are not "Name" and "ID"), you will get a 404 Not Found error message. 311 | 312 | For example: 313 | 314 | post not found curl 315 | 316 | ##### 3.1.7.3 Other method 317 | 318 | The HTTP server will not handle HTTP requests except GET requests and POST requests. 319 | 320 | If you send a HTTP DELETE (or PUT, HEAD, etc.) request to delete the specified resource, you will get a 501 Not Implemented error message: 321 | 322 | Not implemented 323 | 324 | #### 3.1.8 Implementation requirements 325 | 326 | ##### 3.1.8.1 Basic version 327 | 328 | Your program should complete all the **tasks described in section `3.1.1~3.1.7` except `3.1.3`**. 329 | 330 | In the basic version, you have **only one request per TCP connection going on at the same time**. The client waits for response, and when it gets response, perhaps reuses the TCP connection for a new request (or use a new TCP connection). This is also what normal HTTP server supports. 331 | 332 | ##### 3.1.8.2 Advanced version 333 | 334 | Your program should complete all the **tasks described in section `3.1.1~3.1.7` including`3.1.3`**. 335 | 336 | In the advanced version, **multiple http requests can be fired concurrently on one TCP connection**. This is also called HTTP pipelining which is supported by many real browsers and servers (such as Chrome). Note that HTTP requests that come from the same TCP connection should be responded in the same order. So take care the order problem when using complex multi-thread styles. 337 | 338 | ### 3.2 Finish a performance test report 339 | Please test your code first, and commit a test report along with your lab code into your group’s course github repo. 340 | 341 | The test report should describe the performance result under various testing conditions. Specifically, in your test report, you should at least contain the following two things: 342 | 343 | 1. Test how many HTTP request your server can process per second, when running on various server machine environments. For example, change the number of server CPU cores, enable/disable hyper-threading, etc. 344 | 2. Test how many HTTP request your server can process per second, by varying the number of concurrent clients that send request to your server simultaneously. Do change the client's workload. For example, test when a client use new TCP connection for a new request, or when a client reuses old TCP connection for new requests. Moreover, if you implement the advanced version, try to change the number of out-bounding requests on the same client's TCP connection. You can write a simple client that send HTTP Get by your own (can run multiple client programs on the same machine to emulate multiple clients), or use some existing HTTP client testing tools such as [ab - Apache HTTP server benchmarking tool](http://httpd.apache.org/docs/current/programs/ab.html). 345 | 346 | **[NOTE]**: Be careful that clients may be the performance bottleneck. So you'd better use multiple machines when testing the performance. For example, you can run multiple client processes on three machines (of three group members), and run the server process on another machine (of the other group member). Moreover, the network can be the bottleneck too. You can estimate the performance limit according to the physical bandwidth of your network environment, and see if your implementation can reach the performance limit. 347 | 348 | 349 | ## 4. Lab submission 350 | 351 | Please put all your code in folder `Lab2` and write a `Makefile` so that we **can compile your code in one single command** `make`. The compiled runnable executable binary should be named `httpserver` and located in folder `Lab2`. Please carefully following above rules so that TAs can automatically test your code!!! 352 | 353 | Please submit your lab program and performance test report following the guidance in the [Overall Lab Instructions](../README.md) (`../README.md`) 354 | 355 | ## 5. Grading standards 356 | 357 | 1. You can get 23 points if you can: 1) finish all the requirements of the basic version, and 2) your performance test report has finished the two requirements described before. If you missed some parts, you will get part of the points depending how much you finished. 358 | 2. You can get 25 points (full score) if you can: 1) finish all the requirements of the advanced version, and 2) your performance test report has finished the two requirements described before. If you missed some parts, you will get part of the points depending how much you finished. -------------------------------------------------------------------------------- /Lab2/src/get_404_curl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab2/src/get_404_curl.png -------------------------------------------------------------------------------- /Lab2/src/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab2/src/index.png -------------------------------------------------------------------------------- /Lab2/src/index_curl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab2/src/index_curl.png -------------------------------------------------------------------------------- /Lab2/src/not_implemented.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab2/src/not_implemented.png -------------------------------------------------------------------------------- /Lab2/src/not_implemented_curl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab2/src/not_implemented_curl.png -------------------------------------------------------------------------------- /Lab2/src/post_404_curl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab2/src/post_404_curl.png -------------------------------------------------------------------------------- /Lab2/src/post_curl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab2/src/post_curl.png -------------------------------------------------------------------------------- /Lab3/README.md: -------------------------------------------------------------------------------- 1 | # Lab 3: A Simple Distributed Key-Value Store 2 | 3 | Enter in the folder you have cloned from our lab git repo, and pull the latest commit. 4 | 5 | `git pull` 6 | 7 | You can find this lab3's instruction in `Lab3/README.md` 8 | 9 | All materials of lab3 are in folder `Lab3/` 10 | 11 | ## 1. Overview 12 | 13 | Implement a simple distributed in-memory key-value database (KV store) by your own, using two-phase commit protocol to guarantee the consistency and robustness of your KV store. 14 | 15 | ### Goals 16 | 17 | * Get to know the problems and difficulties in building a distributed system; 18 | * Know how to use a simple protocol to maintain consistency between multiple distributed servers; 19 | * Use some simple schemes to handle server failures. 20 | 21 | ## 2. Background 22 | 23 | ### 2.1 KV store 24 | 25 | An in-memory key-value database (also called **key-value store**, or **KV store** in this document) is a database that keeps all its data in the main memory and uses a simple key-value data structure. 26 | 27 | Typically, a KV-store exposes the following methods for users to store/delete/read data to/from the databases: 28 | 29 | - **set(key, value)**: stores the value "value" with the key "key" (some KV stores also call this command as "**put**"). 30 | - **del(key)**: deletes any record associated with the key "key". 31 | - **value=get(key)**: retrieves and returns the value associated with the key "key". 32 | 33 | In practice, in-memory KV store serves most user requests only with data stored in the main memory, meanwhile, it often backups its data in the hard disks thus to be durable. However, in this lab, you are not required to consider the data durability (i.e., you can only store the data in main memory). 34 | 35 | ### 2.2 Distributed KV store 36 | 37 | In large-scale cloud services, KV stores are often built in distributed manner, for the sake of **performance and robustness**. 38 | 39 | For example, a KV store may distribute its data in multiple server machines, and simultaneously use those servers to serve user requests. As such, user requests can be evenly balanced to multiple servers when the load is high, and the database can survive from the failure of some servers. 40 | 41 | However, when the KV database is distributed, many problems arise. Among those problems, **consistency issue** may be most notorious and toughest one. For example, assume that a KV database uses two servers A and B to hold data and serve user requests. When user 1 put some key at server A, and then after a very short time user 2 and 3 each posts a get request of this key to server A and B, respectively, then how to make sure that user 2 and 3 both **get the same latest value of this key**? What is more challenging, failures can happen on servers and networks when users are posting requests. 42 | 43 | Next, we will introduce a very simple but classic protocol to ensure consistency among distributed database servers. 44 | 45 | ### 2.3 Two-phase commit 46 | 47 | Now we describe possibly the simplest (but it works!) consensus protocol called **two-phase commit**, or **2PC**. This protocol can ensure the data consistency when the database is located on multiple distributed servers, that is, **two or more machines agree to do something, or not do it, atomically**. Note that this is only a very short introduction. You are encouraged to search more materials if you have further questions (e.g., [this](https://www.bilibili.com/video/BV1at411y7iQ) is a good video about 2PC). 48 | 49 | Frist, 2PC maintains a **commit log** on each machine, which keeps track of whether commit has happened. Log is used to guarantee that all machines either commit or don’t. 50 | 51 | Second, there is **one global coordinator**. It receives transactions from clients (e.g., set/delete/get) and reply results to clients, and coordinates multiple database servers, to ensure either all servers commit the transaction or all abort it. 52 | 53 | Based on above architecture, 2PC operates in two distinct phases: 54 | 55 | 1) The first phase is **prepared phase**. The global coordinator requests that all database servers (called participants) will promise to commit or rollback the transaction (e.g., set or delete a key) . Participants record promise in log, then acknowledge. If anyone votes to abort, coordinator writes "Abort" in its log and tells everyone to abort; each records "Abort" in log. 56 | 57 | 2) The second phase is **commit-or-abort phase**. After all participants respond that they are prepared, then the coordinator writes "Commit" to its log. Then the coordinator asks all participants to commit; All participants respond with ACK. After receive ACKs, the coordinator writes "Got Commit" to log. 58 | 59 | two phase commit 60 | 61 | The detailed steps in 2PC are as follows: 62 | 63 | ***Prepared phase:*** 64 | 65 | 1) To commit the transaction, the coordinator starts by sending a **REQUEST-TO-PREPARE** message to each 66 | participant. 67 | 68 | 2) The coordinator waits for all participants to "vote" on the request. 69 | 70 | 3) In response to receiving a **REQUEST-TO-PREPARE** message, each participant votes by sending a message back to the coordinator, as follows: 71 | 72 | - It votes **PREPARED** if it is prepared to commit. 73 | - It may vote **NO** for any reason, usually because it cannot prepare the transaction due to a local failure. 74 | - It may delay voting indefinitely, for example, because the network drops the vote. 75 | 76 | ***Commit-Or-Abort phase:*** 77 | 78 | 1) If the coordinator receives **PREPARED** messages from all participants, it decides to commit. The transaction is now officially committed. Otherwise, it either received a **NO** message or gave up waiting for some participant, so it decides to abort. 79 | 80 | 2) The coordinator sends its decision to all participants (i.e.,**COMMIT** or **ABORT**). 81 | 82 | 3) Participants acknowledge receipt of the commit or abort by replying **DONE**. 83 | 84 | 4) After receiving **DONE** from all participants, the coordinator can reply clients with the transaction result (either success or failed), and *forget* the transaction, meaning that it can deallocate any memory it was using to keep track of information about the transaction. 85 | 86 | ## 3. Your Lab Task 87 | 88 | ### 3.1 Task overview 89 | 90 | KVStoreOverview 91 | 92 | You need to implement a simple distributed KV store. Your KV store should run as a network service on remote machine(s), which can receive clients' operations on the database and return results to clients, through network messages. To cope with failures, your are required to implement your KV store services on multiple machines (which are connected with each other through network). Use 2PC protocol to maintain database consistency among multiple machines. 93 | 94 | To simplify the task, your KV store data is only stored in main memory. Also, the log in 2PC protocol is also only stored in main memory. 95 | 96 | Detailed lab requirements are discussed below. 97 | 98 | ### 3.2 KV store command formats 99 | 100 | Your KV store servers are only required to support three database commands: `SET`, `GET` and `DEL` commands (case sensitive). These commands (including arguments) and the return results are encapsulated into network messages using dedicated message format. For simplicity, all the keys and values are stored as strings in your KV store. 101 | 102 | Further details are as follows: 103 | 104 | #### 3.2.1 Network message format 105 | 106 | In this lab, you should use a **simplified version** of RESP (REdis Serialization Protocol) message format to pass KV store commands from clients to servers (called request message) and pass command results from server to clients (called response message) . Specifically: 107 | 108 | ##### 3.2.1.1 Client request message 109 | 110 | Clients send commands to the server using RESP Arrays (more details see `section 3.2.2`). RESP Arrays consist of: 111 | 112 | - A `*` character as the first byte, followed by the number of elements in the array as a decimal number, followed by CRLF. 113 | - Arbitrary number of bulk strings (up to 512 MB in length). 114 | 115 | The bulk string consist of: 116 | 117 | - A `$` byte followed by the number of bytes composing the string (a prefixed length), terminated by CRLF. 118 | - The actual string data. 119 | - A final CRLF. 120 | 121 | For example, the string `CS06142` is encoded as follows: 122 | 123 | `$7\r\nCS06142\r\n` 124 | 125 | The bulk string `$7\r\nCS06142\r\n` start with a `$` byte, and the following number 7 indicate that the length of string `CS06142` is 7. Then, the terminated CRLF, actual string data `CS06142` and the final CRLF are next, consecutively. 126 | 127 | ##### 3.2.1.2 Server response message 128 | 129 | 1) Success message: 130 | 131 | Success messages are encoded in the following way: a plus '+' character, followed by a string that cannot contain a CR or LF character (no newlines are allowed), terminated by CRLF (that is "\r\n"). 132 | 133 | For example, the `SET` command reply with just "OK" on success (more details see `section 3.2.2`): 134 | 135 | `+OK\r\n` 136 | 137 | 2) Error message: 138 | 139 | Like success messages, error messages consist of: a minus '-' character, followed by a string, terminated by CRLF. 140 | 141 | For example, if an error occurs, just return (more details see `section 3.2.2`): 142 | 143 | `-ERROR\r\n` 144 | 145 | 3) RESP Arrays message: 146 | 147 | Your server should return an RESP Arrays message when the `GET` command executed successfully (more detail see `section 3.2.2`). 148 | 149 | For example: 150 | 151 | `*2\r\n$5\r\nCloud\r\n$9\r\nComputing\r\n` 152 | 153 | 4) Integer message: 154 | 155 | Some commands need to return an integer (e.g., `DEL` command, more details see `section 3.2.2`). An integer message is just a CRLF terminated string representing an integer, prefixed by a ":" byte. 156 | 157 | An integer message example: 158 | 159 | `:1\r\n` 160 | 161 | #### 3.2.2 Database commands 162 | 163 | ##### 3.2.2.1 SET command 164 | 165 | `SET key value` 166 | 167 | The function of the `SET` command is to set **key** to hold the string **value**. If key already holds a value, it is overwritten. For example, if you want to set key `CS06142` to hold the string `Cloud Computing`, the command would be: 168 | 169 | `SET CS06142 "Cloud Computing"` 170 | 171 | According to the message format we have discussed in `section 3.2.1`, this command would be encoded as a RESP message format: 172 | 173 | `*4\r\n$3\r\nSET\r\n$7\r\nCS06142\r\n$5\r\nCloud\r\n$9\r\nComputing\r\n` 174 | 175 | **Note:** The encoded message start with a `*` byte. The following number 4 indicate that there are 4 bulk strings in this message. These bulk strings are `$3\r\nSET\r\n`, `$7\r\nCS06142\r\n`, `$5\r\nCloud\r\n`, and `$9\r\nComputing\r\n`. 176 | 177 | 178 | If the `SET` operation succeeds, the server will return a success message; otherwise, return an error message. 179 | 180 | For example, if the `SET` operation succeeds, the server just returns: 181 | 182 | `+OK\r\n` 183 | 184 | Otherwise, it returns: 185 | 186 | `-ERROR\r\n` 187 | 188 | ##### 3.2.2.2 GET command 189 | 190 | `GET key` 191 | 192 | `GET` command can get the **value** of **key**. If the key does not exist the special value `nil` is returned. 193 | 194 | For example, if you want to check the value of the key `CS06142`, construct the command like this: 195 | 196 | `GET CS06142` 197 | 198 | Like the `GET` command, this command should be encoded as a specific message format before sending to the server. 199 | 200 | `*2\r\n$3\r\nGET\r\n$7\r\nCS06142\r\n` 201 | 202 | If the `GET` command was executed correctly, the value (encoded as RESP Arrays format) of the key will be returned. 203 | 204 | For example, if the command above executed correctly, return: 205 | 206 | `*2\r\n$5\r\nCloud\r\n$9\r\nComputing\r\n` 207 | 208 | , assuming the value of the key `CS06142` is`Cloud Computing`. 209 | 210 | If the key does no exist, just return: 211 | 212 | `*1\r\n$3\r\nnil\r\n` 213 | 214 | If an error occurs, return an error message: 215 | 216 | `-ERROR\r\n` 217 | 218 | ##### 3.2.2.3 DEL command 219 | 220 | `DEL key1 key2 ...` 221 | 222 | The `DEL` command is used for removing one or more specified **keys** (arbitrary number, up to 512 MB message length). A key is ignored if it does not exist. 223 | 224 | The `DEL` command should return the number of keys that were removed. 225 | 226 | For example, if you want to delete key `CS06142` and key `CS162`, you can construct the `DEL` command: 227 | 228 | `DEL CS06142 CS162` 229 | 230 | Similar to the `SET` and `GET` commands, the `DEL` command will be encoded in RESP message as follows: 231 | 232 | `*3\r\n$3\r\nDEL\r\n$7\r\nCS06142\r\n$5\r\nCS162\r\n` 233 | 234 | The server will return the number of keys that were removed. 235 | 236 | For example, if the `DEL` command above executed, return an integer message: 237 | 238 | `:1\r\n` 239 | 240 | **note:** Because we only set the key `CS06142` to hold a value. As for key `CS162`, it will be ignored because it does no exist. So, the number in the integer message is 1. 241 | 242 | If an error occurs, return an error message: 243 | 244 | `-ERROR\r\n` 245 | 246 | ### 3.3 Use 2PC protocol to build a KV store on multiple servers 247 | 248 | You should implement the coordinator and participant program. 249 | 250 | The **coordinator** does not store any data. It only receives and parses KV commands from clients, runs 2PC protocol to coordinates participants to conduct the KV commands consistently, and reply command results to clients. *There is only one coordinator in the whole system*. 251 | 252 | Each **participant** maintains a KV database in its main memory, and conduct KV commands sent from the coordinator, and return results to the coordinator. 253 | 254 | You can use any message format for communication between the coordinator and participants. For example, you can also use the RESP format introduced before, or use some other RPC library. 255 | 256 | ### 3.4 Run your program 257 | 258 | #### 3.4.1 Program arguments 259 | 260 | Enable long options to accept arguments in your program, just like lab2. There should be one and only one argument for your program: `--config_path`, which specifies the path of the configuration file. All the detailed configurations are written in the configuration file. Your program should read and parse the configuration file, and run as coordinator or participant accordingly. 261 | 262 | If your program is called **kvstore2pcsystem**: 263 | 264 | run the **coordinator** process, just typing (`./src/coordinator.conf` is the coordinator's configuration file) 265 | 266 | `./kvstore2pcsystem --config_path ./src/coordinator.conf` 267 | 268 | run the **participant** process, just typing (`./src/participant.conf` is the participant's configuration file) 269 | 270 | `./kvstore2pcsystem --config_path ./src/participant.conf` 271 | 272 | When you run the command above, your program should run correctly without any further inputs. 273 | 274 | #### 3.4.2 Configuration file format 275 | 276 | A configuration file consists of two kinds of lines: 1) parameter line, and 2) comment line. 277 | 278 | - **A comment line** starts with a character '!'. The whole comment line are not parsed by the program. 279 | - **A parameter line** starts with a *parameter*, followed by a *value*. The parameter and value are separated by a whitespace. Parameter lines specify the necessary information that the coordinator or participants should know before running. There are three valid parameters: `mode`, `coordinator_info`, and `participant_info`. 280 | - The parameter `mode` specifies that whether the program runs as a coordinator or a participant. Its value should only be either `coordinator` or `participant`. `mode` line is always *the first parameter line* in the configuration file. 281 | - The parameter `coordinator_info` specifies the network address that the coordinator is listening on. Its value consists of the IP address and port number (separated by character ':'). Clients and participants can communicate with the coordinator using this network address. Since there is only one coordinator, there is only one `coordinator_info` line in both coordinator's and participants' configuration file. 282 | - The parameter `participant_info` consists of the network address that participant process is listening on. Its value consists of the IP address and port number (separated by character ':'). The coordinator can communicate with the participant using this network address. For participants, there is only one `participant_info` line in the configuration file, specifying its own network address; For the coordinator, there can be multiple `participant_info` lines in the configuration file, specifying the network addresses of all participants. 283 | 284 | Sample coordinator configuration file: 285 | 286 | ``` 287 | ! 288 | ! Coordinator configuration 289 | ! 2020/05/07 11:25:33 290 | ! 291 | ! The argument name and value are separated by whitespace in the configuration file. 292 | ! 293 | ! Mode of process, coordinator OR participant 294 | mode coordinator 295 | ! 296 | ! The address and port the coordinator process is listening on. 297 | ! Note that the address and port are separated by character ':'. 298 | coordinator_info 127.0.0.1:8001 299 | ! 300 | ! Address and port information of all participants. 301 | ! Three lines specifies three participants' addresses. 302 | participant_info 127.0.0.1:8002 303 | participant_info 127.0.0.1:8003 304 | participant_info 127.0.0.1:8004 305 | ``` 306 | 307 | Sample participant configuration file: 308 | 309 | ``` 310 | ! 311 | ! Participant configuration 312 | ! 2020/05/07 11:25:33 313 | ! 314 | ! The argument name and value are separated by whitespace in the configuration file. 315 | ! 316 | ! Mode of process, coordinator OR participant 317 | mode participant 318 | ! 319 | ! The address and port the participant process is listening on. 320 | participant_info 127.0.0.1:8002 321 | ! 322 | ! The address and port the coordinator process is listening on. 323 | coordinator_info 127.0.0.1:8001 324 | ``` 325 | 326 | ### 3.5 Implementation requirements 327 | 328 | #### 3.5.1 Basic version 329 | 330 | Your program should complete all the tasks described in `section 3.1-3.4`. Your system is required to correctly receive and conduct the KV commands, and reply the corresponding results, as described before. 331 | 332 | In the basic version, there will be **no participant failures**. Also, we will **not inject any network failures**. However, the network may still drop packets occasionally. You can use TCP to handle such occasional drops. 333 | 334 | **The coordinator process may be killed and restart at any time for multiple times**. So do not store any database data in the coordinator. The coordinator will deal with clients' KV commands when it is working. When the coordinator is killed, your system is not required to reply any client's commands. Clients will keep retransmit its KV commands until it gets success response from the coordinator. The coordinator remembers no history (except for the information in the configuration file), so it will deal with all commands as new ones after it restarts. 335 | 336 | Your program should run correctly with 3 or more participants. 337 | 338 | #### 3.5.2 Advanced version 339 | 340 | Your program should complete all the tasks described in `section 3.1-3.4`. Your system is required to correctly receive and conduct the KV commands, and reply the corresponding results, as described before. 341 | 342 | In the advanced version, **participants may fail, and the network links may fail**. However, the participant and network link **failures are one-shot**, that is, if they fail, they will never come back again. Also, **the coordinator process may be killed and restart at any time for multiple times**. The coordinator will deal with clients' KV commands when it is working. When the coordinator is killed, your system is not required to reply any client's commands. 343 | 344 | When the coordinator is working, it should be able to detect the failure of participants. You can use some periodical heartbeat messages to detect the participant failure (e.g., no reply after certain number of heartbeats). **Once a participant is dead, the coordinator should be able to remove it from the system, and correctly receive/conduct/reply clients' KV commands with the rest participants**. If all participants fail, the coordinator will always reply ERROR to the clients' KV commands. The coordinator remembers no history (except for the information in the configuration file), so it need to redetect all the participants' liveness after restart. 345 | 346 | Your program should run correctly with 3 or more participants. 347 | 348 | **NOTE**: **Groups that have registered for demo 3 should at least finish the advanced version.** 349 | 350 | #### **3.5.3 Extreme version** 351 | 352 | Your program should complete all the tasks described in `section 3.1-3.4`. Your system is required to correctly receive and conduct the KV commands, and reply the corresponding results, as described before. 353 | 354 | In the extreme version, **participants may fail, and the network links may fail**. The participant and network link **failures can be both permanent or transient**, that is, if they fail, they may come back again at any time. Also, **the coordinator process may be killed and restart at any time for multiple times**. The coordinator will deal with clients' KV commands when it is working. When the coordinator is killed, your system is not required to reply any client's commands. 355 | 356 | When the coordinator is working, it should be able to detect **both failure and recovery** of participants. Once a participant is dead, the coordinator should be able to remove it from the system; Once a participant is recovered, the coordinator should be able to add it back to the system. Note that to keep database consistent, after a participant recovers from failure, you should copy the latest KV store database from some working participants to this recovered participant. We will not provide any copy protocols for you. You are encouraged to devise your own schemes as long as it is correct. You should be very careful about the consistency issue since the failures can be very complex and random. For example, considering the case that there are two participants A and B, A fails first and then A comes back and B fails later. During this procedure, client's may keep sending KV commands, so A needs to sync those new KV commands after coming back, otherwise it cannot server client's request correctly after B fails. 357 | 358 | We will randomly inject failure and recovery to all the participants and network links. To ensure the database can be successfully copied, during our test, after a participant (or its network link) is recovered from failure, we will ensure that *no failures happen in the following 10 seconds* (no coordinator/participant/network failure). Your coordinator should be able to copy the latest database to the newly recovered participant in this 10 seconds. Moreover, we will always ensure that *there is at least one working participant* in the system. As such, the coordinator should be able to correctly receive/conduct/reply clients' KV commands during the failures and recoveries. 359 | 360 | Your program should run correctly with 3 or more participants. 361 | 362 | **NOTE**: **Groups that have registered for demo 4 should at least finish the extreme version.** 363 | 364 | #### **3.5.6 Ultimate version** 365 | 366 | Since the coordinator may permanently fail, your system should also **be able to deal with clients' requests even when coordinator fails**. 2PC is not able to handle this problem. So in this version, you will not use 2PC protocol, but use some advanced consensus protocol to handle this case. 367 | 368 | You can implement multiple KV store servers, where each server can receive requests from clients, stores data, and reply responses. Clients are preconfigured with all servers' addresses, and may send KV commands to any of the server, randomly. To keep consistency, normally there is only one leader server that deal with all the clients' requests, and backup the data in other servers. Clients' commands to other servers are all redirected to the leader. The consensus protocol can help servers to detect the failure of the leader server, and reelect a new leader. Also, the consensus protocol can help to maintain database consistency among multiple servers. 369 | 370 | [Raft](https://raft.github.io/) is a very good consensus protocol for this purpose. You may want to read its paper by yourself and use raft to implement this version (there are many open-sourced raft implementation that you can borrow). Sorry I'm not going to teach you this :) Of course, it is always good to use other consensus protocols or even your own schemes. 371 | 372 | **NOTE**: **This version is very difficult, so it is not compulsory but just a challenge. Have fun!** 373 | 374 | ## 4. Lab submission 375 | 376 | Please put all your code in folder `Lab3` and write a `Makefile` so that we **can compile your code in one single command** `make`. The compiled runnable executable binary should be named `kvstore2pcsystem` and located in folder `Lab3`. Please carefully following above rules so that TAs can automatically test your code!!! 377 | 378 | You can use any available code or library for this lab. Please search the Internet. However, do not copy other teams' code. No performance test report is required for this lab. Enjoy the lab :) 379 | 380 | Please submit your lab program following the guidance in the [Overall Lab Instructions](../README.md) (`../README.md`) 381 | 382 | ## 5. Grading standards 383 | 384 | 1. You can get 13 points if you can finish all the requirements of the basic version. If you missed some parts, you will get part of the points depending how much you finished. 385 | 2. You can get 21 points if you can finish all the requirements of the advanced version. If you missed some parts, you will get part of the points depending how much you finished. 386 | 3. You can get 24 points if you can finish all the requirements of the extreme version. If you missed some parts, you will get part of the points depending how much you finished. 387 | 4. You can get 25 points if you can finish all the requirements of the ultimate version. If you missed some parts, you will get part of the points depending how much you finished. -------------------------------------------------------------------------------- /Lab3/src/KVStoreOverview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab3/src/KVStoreOverview.jpg -------------------------------------------------------------------------------- /Lab3/src/KVStoreOverview.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab3/src/KVStoreOverview.pptx -------------------------------------------------------------------------------- /Lab3/src/coordinator_sample.conf: -------------------------------------------------------------------------------- 1 | ! 2 | ! Coordinator configuration 3 | ! 2020/05/07 11:25:33 4 | ! 5 | ! The argument name and value are separated by whitespace in the configuration file. 6 | ! 7 | ! Mode of process, coordinator OR participant 8 | mode coordinator 9 | ! 10 | ! The address and port the coordinator process is listening on. 11 | ! Note that the address and port are separated by character ':'. 12 | coordinator_info 127.0.0.1:8001 13 | ! 14 | ! Address and port information of all participants. 15 | ! Three lines specifies three participants' addresses. 16 | participant_info 127.0.0.1:8002 17 | participant_info 127.0.0.1:8003 18 | participant_info 127.0.0.1:8004 -------------------------------------------------------------------------------- /Lab3/src/participant_sample.conf: -------------------------------------------------------------------------------- 1 | ! 2 | ! Participant configuration 3 | ! 2020/05/07 11:25:33 4 | ! 5 | ! The argument name and value are separated by whitespace in the configuration file. 6 | ! 7 | ! Mode of process, coordinator OR participant 8 | mode participant 9 | ! 10 | ! The address and port the participant process is listening on. 11 | participant_info 127.0.0.1:8002 12 | ! 13 | ! The address and port the coordinator process is listening on. 14 | coordinator_info 127.0.0.1:8001 -------------------------------------------------------------------------------- /Lab3/src/two-phase-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxthnu/CloudComputingLabs/74dcd2c1e4dd5d97615173a6aaedc7927bac9c07/Lab3/src/two-phase-commit.png -------------------------------------------------------------------------------- /Lab4/README.md: -------------------------------------------------------------------------------- 1 | # Lab 4: A "Serious" Web-Retail System -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cloud Computing: Overall Lab Instruction 2 | 3 | 4 | 5 | ## 1. Overview 6 | 7 | There are **4 labs in total** in this course. All the materials of each lab are under folders Lab1-4 in this repo. Please clone the lab git repo onto your local computer, 8 | 9 | `git clone https://github.com/1989chenguo/CloudComputingLabs.git` 10 | 11 | and always track our latest lab materials using the following commands (should first enter the folder you have cloned from our lab repo) 12 | 13 | `git pull` 14 | 15 | You can find this overall lab instruction in `README.md` in the root folder. 16 | 17 | Please **carefully read the overall lab instruction before you do anything**. 18 | 19 | Also, please **carefully read each lab's instruction** ([Lab1](Lab1/README.md), [Lab2](Lab2/README.md), [Lab3](Lab3/README.md), [Lab4](Lab4/README.md)) to get each lab's task, background, requirements, etc. 20 | 21 | ## 2. Group collaboration 22 | 23 | Each student should register your own github account. Group members should use **git and github** to collaborate. 24 | 25 | All the labs are done in the unit of group, i.e., a group only needs to submit one piece of code for each lab. However, each group member should make enough contribution to the lab. Teaching assistants will check the **git commit history** to evaluate each one’s contribution. 26 | 27 | ## 3. Code submission 28 | 29 | Each group should create a code repo for our course (create your own group's repo, do not push onto my course lab repo!). The group leader should send an email to TA telling us your group's lab git repo address. For example, https://github.com/group1/CloudComputingLabs.git` 30 | 31 | **All the lab code should be submitted through pushing to your group's github code repo.** Teaching assistants will checkout your commit, and read and test your codes from the above repo address you provided us. The code of different lab should be in different folders, named Lab1/Lab2/Lab3/Lab4, respectively (following the same structure of this repo). Please note that your lab folder name should be exactly same as above (be careful about the first capital letter and no space before the number), otherwise your code may fail in our TAs' automatic testing scripts. All lab codes should be in the same course git repo of your group. 32 | 33 | Please write a README.md to each lab code folder, briefly introducing how to run your lab code (including how to set the environment, provide the input, and explain the output, etc.). Keep the README short and clear! Also, your code should be well commented so that other people can understand without asking you. 34 | 35 | ## 4. Environment requirement 36 | 37 | ### 4.1 OS requirement 38 | 39 | All the labs should be tested and runnable on UNIX-like operating systems, such as Linux distributions (e.g., Ubuntu, CentOS) and MacOS. We highly recommend you to use Linux distributions such as Ubuntu. 40 | If you only have windows PC or laptops, install a UNIX VM and do experiments on the VM. 41 | 42 | ### 4.2 Programming language 43 | 44 | Any programming languages are permitted in all labs, such as C/C++, Java, Go, Python, Perl. But for performance consideration, we highly recommend you to use C/C++ or Go !!! 45 | 46 | ### 4.3 Try to only use standard API 47 | 48 | To make your program portable, try your best to only use standard & widely available functions and normal libraries (such as `glibc`, `C++ STLs` and some typical math libraries). All the labs should only use standard system API defined by POSIX specification or Linux man page specification. We prefer to use standard POSIX API, so your code can be easily runnable on various kind of UNIX-like systems (instead of only on Linux). 49 | 50 | ## 5. Grading 51 | 52 | Grading details are specified in each lab's instruction document, please carefully read them [Lab1](Lab1/README.md), [Lab2](Lab2/README.md), [Lab3](Lab3/README.md), [Lab4](Lab4/README.md). 53 | 54 | Besides, we have the following 3 overall grading requirements applicable to all the 4 labs: 55 | 56 | 1. **DO NOT copy** others' code (either from the Internet or from your classmates), otherwise your group (every member and the leader) will got **zero point** in the lab. However, we encourage to communicate with other group and learn from each other. But do remember to write the code yourself and not copy. 57 | 2. **DO NOT miss the deadline**, otherwise your group (every member and the leader) points will be reduced accordingly. 58 | 3. Typically, your group (every member and the leader) will get same points in each lab, unless we find severely **unfair contribution** in the git commit history. In the overall grading, the leader will get some more points as bonus. 59 | --------------------------------------------------------------------------------