/ scripts / local-benchmark.sh
local-benchmark.sh
  1  #!/bin/bash
  2  # Local benchmark script for KeepSync
  3  # Tests performance of adaptive chunking, encryption, versioning with security focus
  4  
  5  # Set up colors for output
  6  GREEN='\033[0;32m'
  7  RED='\033[0;31m'
  8  YELLOW='\033[1;33m'
  9  BLUE='\033[0;34m'
 10  NC='\033[0m' # No Color
 11  
 12  # Set up variables
 13  TEST_DIR="./benchmark-results"
 14  TIMESTAMP=$(date +%Y%m%d-%H%M%S)
 15  RESULTS_DIR="$TEST_DIR/$TIMESTAMP"
 16  REPORT_FILE="$RESULTS_DIR/benchmark-report.md"
 17  SUMMARY_FILE="$RESULTS_DIR/summary.csv"
 18  
 19  # Default settings
 20  ITERATIONS=3
 21  FILE_SIZES=("1M" "10M" "100M")
 22  # Adaptive chunk sizes based on file size
 23  SMALL_CHUNK_SIZES=("512K" "1M" "2M")
 24  MEDIUM_CHUNK_SIZES=("1M" "2M" "4M")
 25  LARGE_CHUNK_SIZES=("2M" "4M" "8M")
 26  ENCRYPTION_ALGORITHMS=("AES-256-GCM")
 27  COMPRESSION_LEVELS=(0 6)
 28  # Parse command line arguments
 29  QUIET_MODE=false
 30  for arg in "$@"; do
 31      case $arg in
 32          --quiet)
 33              QUIET_MODE=true
 34              ;;
 35      esac
 36  done
 37  DIFF_ALGORITHMS=("bsdiff" "vcdiff")
 38  
 39  # Create directories
 40  mkdir -p "$RESULTS_DIR/test-files"
 41  
 42  # Initialize report file
 43  cat > "$REPORT_FILE" << EOF
 44  # KeepSync Benchmark Report
 45  
 46  **Date:** $(date)
 47  **System:** $(uname -a)
 48  **CPU:** $(grep "model name" /proc/cpuinfo | head -n 1 | cut -d ':' -f 2 | xargs)
 49  **Memory:** $(free -h | grep "Mem:" | awk '{print $2}')
 50  
 51  ## Benchmark Configuration
 52  
 53  - **Iterations:** $ITERATIONS
 54  - **File Sizes:** ${FILE_SIZES[*]}
 55  - **Small File Chunk Sizes (<10MB):** ${SMALL_CHUNK_SIZES[*]}
 56  - **Medium File Chunk Sizes (10-100MB):** ${MEDIUM_CHUNK_SIZES[*]}
 57  - **Large File Chunk Sizes (>100MB):** ${LARGE_CHUNK_SIZES[*]}
 58  - **Encryption Algorithms:** ${ENCRYPTION_ALGORITHMS[*]}
 59  - **Compression Levels:** ${COMPRESSION_LEVELS[*]}
 60  - **Diff Algorithms:** ${DIFF_ALGORITHMS[*]}
 61  
 62  ## Summary
 63  
 64  The summary will be generated after all benchmarks are complete.
 65  
 66  ## Detailed Results
 67  
 68  EOF
 69  
 70  # Initialize summary file
 71  echo "Test,Configuration,FileSize,AvgTime(s),Throughput(MB/s),SecurityScore" > "$SUMMARY_FILE"
 72  
 73  # Function to convert size string to bytes
 74  size_to_bytes() {
 75      local size=$1
 76      local unit=${size: -1}
 77      local value=${size%?}
 78      
 79      case $unit in
 80          K)
 81              echo $((value * 1024))
 82              ;;
 83          M)
 84              echo $((value * 1024 * 1024))
 85              ;;
 86          G)
 87              echo $((value * 1024 * 1024 * 1024))
 88              ;;
 89          *)
 90              echo $value
 91              ;;
 92      esac
 93  }
 94  
 95  # Function to create test files
 96  create_test_files() {
 97      echo -e "${YELLOW}Creating test files...${NC}"
 98      
 99      for size in "${FILE_SIZES[@]}"; do
100          echo -e "${YELLOW}Creating $size test file...${NC}"
101          
102          # For text files (better compression)
103          dd if=/dev/urandom bs=1024 count=$(($(size_to_bytes "$size") / 1024)) 2>/dev/null | base64 > "$RESULTS_DIR/test-files/text-$size.txt"
104          
105          # For binary files (worse compression, better for diff testing)
106          dd if=/dev/urandom bs=1024 count=$(($(size_to_bytes "$size") / 1024)) 2>/dev/null > "$RESULTS_DIR/test-files/binary-$size.bin"
107          
108          # Create a second version with small changes (for diff testing)
109          cp "$RESULTS_DIR/test-files/text-$size.txt" "$RESULTS_DIR/test-files/text-$size-v2.txt"
110          sed -i "s/a/b/g" "$RESULTS_DIR/test-files/text-$size-v2.txt"
111          
112          cp "$RESULTS_DIR/test-files/binary-$size.bin" "$RESULTS_DIR/test-files/binary-$size-v2.bin"
113          # Modify ~5% of the binary file
114          dd if=/dev/urandom bs=1024 count=$(($(size_to_bytes "$size") / 1024 / 20)) 2>/dev/null | dd of="$RESULTS_DIR/test-files/binary-$size-v2.bin" conv=notrunc
115      done
116      
117      echo -e "${GREEN}Test files created successfully${NC}"
118  }
119  
120  # Function to calculate security score
121  calculate_security_score() {
122      local encryption=$1
123      local chunk_size=$2
124      local compression=$3
125      
126      # Base score
127      local score=5
128      
129      # Encryption algorithm score
130      case $encryption in
131          "AES-256-GCM")
132              score=$((score + 3))
133              ;;
134          "AES-256-CTR")
135              score=$((score + 2))
136              ;;
137          *)
138              score=$((score + 1))
139              ;;
140      esac
141      
142      # Chunk size score (smaller chunks are more secure for some attack vectors)
143      case $chunk_size in
144          "512K")
145              score=$((score + 3))
146              ;;
147          "1M")
148              score=$((score + 2))
149              ;;
150          "2M")
151              score=$((score + 1))
152              ;;
153          "4M")
154              score=$((score + 0))
155              ;;
156          "8M")
157              score=$((score - 1))
158              ;;
159      esac
160      
161      # Compression can introduce side-channel vulnerabilities
162      if [ "$compression" -gt 0 ]; then
163          score=$((score - 1))
164      fi
165      
166      echo $score
167  }
168  
169  # Function to get appropriate chunk sizes for a file size
170  get_chunk_sizes_for_file() {
171      local file_size=$1
172      local file_size_bytes=$(size_to_bytes "$file_size")
173      
174      if [ $file_size_bytes -lt 10485760 ]; then  # < 10MB
175          echo "${SMALL_CHUNK_SIZES[@]}"
176      elif [ $file_size_bytes -lt 104857600 ]; then  # < 100MB
177          echo "${MEDIUM_CHUNK_SIZES[@]}"
178      else  # >= 100MB
179          echo "${LARGE_CHUNK_SIZES[@]}"
180      fi
181  }
182  
183  # Function to run adaptive chunking benchmark
184  benchmark_adaptive_chunking() {
185      if [ "$QUIET_MODE" = false ]; then
186      echo -e "${YELLOW}Running adaptive chunking benchmarks...${NC}"
187  else
188      echo "Running adaptive chunking benchmarks..."
189  fi
190      
191      # Add to report
192      cat >> "$REPORT_FILE" << EOF
193  
194  ### Adaptive Chunking Benchmarks
195  
196  | File Size | Chunk Size | Avg Time (s) | Throughput (MB/s) | Security Score |
197  |-----------|------------|--------------|-------------------|----------------|
198  EOF
199      
200      for file_size in "${FILE_SIZES[@]}"; do
201          # Get appropriate chunk sizes for this file size
202          chunk_sizes=($(get_chunk_sizes_for_file "$file_size"))
203          
204          for chunk_size in "${chunk_sizes[@]}"; do
205              if [ "$QUIET_MODE" = false ]; then
206              echo -e "${BLUE}Testing adaptive chunking with file size $file_size, chunk size $chunk_size${NC}"
207          fi
208              
209              # Create test file path
210              test_file="$RESULTS_DIR/test-files/binary-$file_size.bin"
211              
212              # Run benchmark iterations
213              total_time=0
214              
215              for ((i=1; i<=ITERATIONS; i++)); do
216                  if [ "$QUIET_MODE" = false ]; then
217                      echo -e "${BLUE}Running iteration $i/${ITERATIONS}...${NC}"
218                  fi
219                  
220                  # Run the benchmark with time measurement
221                  start_time=$(date +%s.%N)
222                  
223                  # Simulate chunking by splitting the file
224                  split -b "$chunk_size" "$test_file" "$RESULTS_DIR/test-files/chunk-"
225                  
226                  end_time=$(date +%s.%N)
227                  
228                  # Calculate time
229                  iteration_time=$(echo "$end_time - $start_time" | bc)
230                  total_time=$(echo "$total_time + $iteration_time" | bc)
231                  
232                  # Clean up chunks
233                  rm "$RESULTS_DIR/test-files/chunk-"*
234                  
235                  if [ "$QUIET_MODE" = false ]; then
236                      echo -e "${BLUE}Iteration $i completed in ${iteration_time}s${NC}"
237                  fi
238              done
239              
240              # Calculate averages
241              avg_time=$(echo "scale=3; $total_time / $ITERATIONS" | bc)
242              
243              # Calculate throughput
244              file_size_bytes=$(size_to_bytes "$file_size")
245              throughput=$(echo "scale=2; $file_size_bytes / 1024 / 1024 / $avg_time" | bc)
246              
247              # Calculate security score
248              security_score=$(calculate_security_score "AES-256-GCM" "$chunk_size" 0)
249              
250              # Add to report
251              echo "| $file_size | $chunk_size | $avg_time | $throughput | $security_score |" >> "$REPORT_FILE"
252              
253              # Add to summary
254              echo "AdaptiveChunking,$chunk_size,$file_size,$avg_time,$throughput,$security_score" >> "$SUMMARY_FILE"
255              
256              if [ "$QUIET_MODE" = false ]; then
257                  echo -e "${GREEN}Adaptive chunking benchmark completed for file size $file_size, chunk size $chunk_size${NC}"
258                  echo -e "${GREEN}Average time: ${avg_time}s, Throughput: ${throughput} MB/s${NC}"
259              fi
260          done
261      done
262      
263      echo -e "${GREEN}Adaptive chunking benchmarks completed${NC}"
264  }
265  
266  # Function to run encryption benchmark
267  benchmark_encryption() {
268      echo -e "${YELLOW}Running encryption benchmarks...${NC}"
269      
270      # Add to report
271      cat >> "$REPORT_FILE" << EOF
272  
273  ### Encryption Benchmarks
274  
275  | File Size | Algorithm | Avg Time (s) | Throughput (MB/s) | Security Score |
276  |-----------|-----------|--------------|-------------------|----------------|
277  EOF
278      
279      for file_size in "${FILE_SIZES[@]}"; do
280          for algorithm in "${ENCRYPTION_ALGORITHMS[@]}"; do
281              echo -e "${BLUE}Testing encryption with file size $file_size, algorithm $algorithm${NC}"
282              
283              # Create test file path
284              test_file="$RESULTS_DIR/test-files/binary-$file_size.bin"
285              
286              # Run benchmark iterations
287              total_time=0
288              
289              for ((i=1; i<=ITERATIONS; i++)); do
290                  if [ "$QUIET_MODE" = false ]; then
291                      echo -e "${BLUE}Running iteration $i/${ITERATIONS}...${NC}"
292                  fi
293                  
294                  # Run the benchmark with time measurement
295                  start_time=$(date +%s.%N)
296                  
297                  # Simulate encryption using OpenSSL
298                  if [ "$algorithm" = "AES-256-GCM" ]; then
299                      openssl enc -aes-256-gcm -k "benchmark-key" -in "$test_file" -out "$RESULTS_DIR/test-files/encrypted-$i.bin" 2>/dev/null
300                  else
301                      # Fallback to AES-256-CTR
302                      openssl enc -aes-256-ctr -k "benchmark-key" -in "$test_file" -out "$RESULTS_DIR/test-files/encrypted-$i.bin" 2>/dev/null
303                  fi
304                  
305                  end_time=$(date +%s.%N)
306                  
307                  # Calculate time
308                  iteration_time=$(echo "$end_time - $start_time" | bc)
309                  total_time=$(echo "$total_time + $iteration_time" | bc)
310                  
311                  # Clean up encrypted file
312                  rm -f "$RESULTS_DIR/test-files/encrypted-$i.bin"
313                  
314                  if [ "$QUIET_MODE" = false ]; then
315                      echo -e "${BLUE}Iteration $i completed in ${iteration_time}s${NC}"
316                  fi
317              done
318              
319              # Calculate averages
320              avg_time=$(echo "scale=3; $total_time / $ITERATIONS" | bc)
321              
322              # Calculate throughput
323              file_size_bytes=$(size_to_bytes "$file_size")
324              throughput=$(echo "scale=2; $file_size_bytes / 1024 / 1024 / $avg_time" | bc)
325              
326              # Calculate security score
327              security_score=$(calculate_security_score "$algorithm" "1M" 0)
328              
329              # Add to report
330              echo "| $file_size | $algorithm | $avg_time | $throughput | $security_score |" >> "$REPORT_FILE"
331              
332              # Add to summary
333              echo "Encryption,$algorithm,$file_size,$avg_time,$throughput,$security_score" >> "$SUMMARY_FILE"
334              
335              echo -e "${GREEN}Encryption benchmark completed for file size $file_size, algorithm $algorithm${NC}"
336              echo -e "${GREEN}Average time: ${avg_time}s, Throughput: ${throughput} MB/s${NC}"
337          done
338      done
339      
340      echo -e "${GREEN}Encryption benchmarks completed${NC}"
341  }
342  
343  # Function to run compression benchmark
344  benchmark_compression() {
345      echo -e "${YELLOW}Running compression benchmarks...${NC}"
346      
347      # Add to report
348      cat >> "$REPORT_FILE" << EOF
349  
350  ### Compression Benchmarks
351  
352  | File Type | File Size | Level | Avg Time (s) | Compression Ratio | Throughput (MB/s) |
353  |-----------|-----------|-------|--------------|-------------------|-------------------|
354  EOF
355      
356      for file_size in "${FILE_SIZES[@]}"; do
357          for file_type in "text" "binary"; do
358              for level in "${COMPRESSION_LEVELS[@]}"; do
359                  echo -e "${BLUE}Testing compression with file type $file_type, file size $file_size, level $level${NC}"
360                  
361                  # Create test file path
362                  if [ "$file_type" = "text" ]; then
363                      test_file="$RESULTS_DIR/test-files/$file_type-$file_size.txt"
364                  else
365                      test_file="$RESULTS_DIR/test-files/$file_type-$file_size.bin"
366                  fi
367                  
368                  # Run benchmark iterations
369                  total_time=0
370                  total_ratio=0
371                  
372                  for ((i=1; i<=ITERATIONS; i++)); do
373                      if [ "$QUIET_MODE" = false ]; then
374                      echo -e "${BLUE}Running iteration $i/${ITERATIONS}...${NC}"
375                  fi
376                      
377                      # Run the benchmark with time measurement
378                      start_time=$(date +%s.%N)
379                      
380                      # Compress the file
381                      output_file="$RESULTS_DIR/test-files/compressed-$i.gz"
382                      if [ "$level" -eq 0 ]; then
383                          # Level 0 means no compression, just copy
384                          cp "$test_file" "$output_file"
385                      else
386                          gzip -c -$level "$test_file" > "$output_file"
387                      fi
388                      
389                      end_time=$(date +%s.%N)
390                      
391                      # Calculate time
392                      iteration_time=$(echo "$end_time - $start_time" | bc)
393                      total_time=$(echo "$total_time + $iteration_time" | bc)
394                      
395                      # Calculate compression ratio
396                      original_size=$(stat -c%s "$test_file")
397                      compressed_size=$(stat -c%s "$output_file")
398                      ratio=$(echo "scale=2; $original_size / $compressed_size" | bc)
399                      total_ratio=$(echo "$total_ratio + $ratio" | bc)
400                      
401                      # Clean up compressed file
402                      rm "$output_file"
403                      
404                      echo -e "${BLUE}Iteration $i completed in ${iteration_time}s, ratio: ${ratio}x${NC}"
405                  done
406                  
407                  # Calculate averages
408                  avg_time=$(echo "scale=3; $total_time / $ITERATIONS" | bc)
409                  avg_ratio=$(echo "scale=2; $total_ratio / $ITERATIONS" | bc)
410                  
411                  # Calculate throughput
412                  file_size_bytes=$(size_to_bytes "$file_size")
413                  throughput=$(echo "scale=2; $file_size_bytes / 1024 / 1024 / $avg_time" | bc)
414                  
415                  # Add to report
416                  echo "| $file_type | $file_size | $level | $avg_time | ${avg_ratio}x | $throughput |" >> "$REPORT_FILE"
417                  
418                  # Add to summary
419                  echo "Compression,$file_type-$level,$file_size,$avg_time,$throughput,N/A" >> "$SUMMARY_FILE"
420                  
421                  echo -e "${GREEN}Compression benchmark completed for file type $file_type, file size $file_size, level $level${NC}"
422                  echo -e "${GREEN}Average time: ${avg_time}s, Ratio: ${avg_ratio}x, Throughput: ${throughput} MB/s${NC}"
423              done
424          done
425      done
426      
427      echo -e "${GREEN}Compression benchmarks completed${NC}"
428  }
429  
430  # Function to run diff benchmark
431  benchmark_diff() {
432      echo -e "${YELLOW}Running diff benchmarks...${NC}"
433      
434      # Check if diff tools are available
435      if ! command -v bsdiff &> /dev/null && ! command -v xdelta3 &> /dev/null; then
436          echo -e "${RED}No diff tools found. Skipping diff benchmarks.${NC}"
437          return
438      fi
439      
440      # Add to report
441      cat >> "$REPORT_FILE" << EOF
442  
443  ### Binary Diff Benchmarks
444  
445  | File Type | File Size | Algorithm | Avg Time (s) | Diff Ratio | Throughput (MB/s) |
446  |-----------|-----------|-----------|--------------|------------|-------------------|
447  EOF
448      
449      for file_size in "${FILE_SIZES[@]}"; do
450          for file_type in "text" "binary"; do
451              for algorithm in "${DIFF_ALGORITHMS[@]}"; do
452                  # Skip if the tool is not available
453                  if [ "$algorithm" = "bsdiff" ] && ! command -v bsdiff &> /dev/null; then
454                      continue
455                  fi
456                  if [ "$algorithm" = "vcdiff" ] && ! command -v xdelta3 &> /dev/null; then
457                      continue
458                  fi
459                  
460                  echo -e "${BLUE}Testing diff with file type $file_type, file size $file_size, algorithm $algorithm${NC}"
461                  
462                  # Create test file paths
463                  if [ "$file_type" = "text" ]; then
464                      test_file1="$RESULTS_DIR/test-files/$file_type-$file_size.txt"
465                      test_file2="$RESULTS_DIR/test-files/$file_type-$file_size-v2.txt"
466                  else
467                      test_file1="$RESULTS_DIR/test-files/$file_type-$file_size.bin"
468                      test_file2="$RESULTS_DIR/test-files/$file_type-$file_size-v2.bin"
469                  fi
470                  
471                  # Run benchmark iterations
472                  total_time=0
473                  total_ratio=0
474                  
475                  for ((i=1; i<=ITERATIONS; i++)); do
476                      if [ "$QUIET_MODE" = false ]; then
477                      echo -e "${BLUE}Running iteration $i/${ITERATIONS}...${NC}"
478                  fi
479                      
480                      # Run the benchmark with time measurement
481                      start_time=$(date +%s.%N)
482                      
483                      # Create diff
484                      output_file="$RESULTS_DIR/test-files/diff-$i.bin"
485                      if [ "$algorithm" = "bsdiff" ] && command -v bsdiff &> /dev/null; then
486                          bsdiff "$test_file1" "$test_file2" "$output_file" 2>/dev/null
487                      elif [ "$algorithm" = "vcdiff" ] && command -v xdelta3 &> /dev/null; then
488                          xdelta3 -e -s "$test_file1" "$test_file2" "$output_file" 2>/dev/null
489                      else
490                          # Fallback to simple diff
491                          diff -u "$test_file1" "$test_file2" > "$output_file" 2>/dev/null
492                      fi
493                      
494                      end_time=$(date +%s.%N)
495                      
496                      # Calculate time
497                      iteration_time=$(echo "$end_time - $start_time" | bc)
498                      total_time=$(echo "$total_time + $iteration_time" | bc)
499                      
500                      # Calculate diff ratio
501                      original_size=$(stat -c%s "$test_file2")
502                      diff_size=$(stat -c%s "$output_file")
503                      ratio=$(echo "scale=2; $original_size / $diff_size" | bc)
504                      total_ratio=$(echo "$total_ratio + $ratio" | bc)
505                      
506                      # Clean up diff file
507                      rm "$output_file"
508                      
509                      echo -e "${BLUE}Iteration $i completed in ${iteration_time}s, ratio: ${ratio}x${NC}"
510                  done
511                  
512                  # Calculate averages
513                  avg_time=$(echo "scale=3; $total_time / $ITERATIONS" | bc)
514                  avg_ratio=$(echo "scale=2; $total_ratio / $ITERATIONS" | bc)
515                  
516                  # Calculate throughput
517                  file_size_bytes=$(size_to_bytes "$file_size")
518                  throughput=$(echo "scale=2; $file_size_bytes / 1024 / 1024 / $avg_time" | bc)
519                  
520                  # Add to report
521                  echo "| $file_type | $file_size | $algorithm | $avg_time | ${avg_ratio}x | $throughput |" >> "$REPORT_FILE"
522                  
523                  # Add to summary
524                  echo "Diff,$algorithm-$file_type,$file_size,$avg_time,$throughput,N/A" >> "$SUMMARY_FILE"
525                  
526                  echo -e "${GREEN}Diff benchmark completed for file type $file_type, file size $file_size, algorithm $algorithm${NC}"
527                  echo -e "${GREEN}Average time: ${avg_time}s, Ratio: ${avg_ratio}x, Throughput: ${throughput} MB/s${NC}"
528              done
529          done
530      done
531      
532      echo -e "${GREEN}Diff benchmarks completed${NC}"
533  }
534  
535  # Function to run versioning benchmark
536  benchmark_versioning() {
537      echo -e "${YELLOW}Running versioning benchmarks...${NC}"
538      
539      # Add to report
540      cat >> "$REPORT_FILE" << EOF
541  
542  ### Versioning Benchmarks
543  
544  | File Size | Operation | Avg Time (s) | Throughput (MB/s) |
545  |-----------|-----------|--------------|-------------------|
546  EOF
547      
548      # Create local versioning directories
549      mkdir -p "$RESULTS_DIR/versions"
550      
551      for file_size in "${FILE_SIZES[@]}"; do
552          # Test file paths
553          test_file="$RESULTS_DIR/test-files/binary-$file_size.bin"
554          test_file_v2="$RESULTS_DIR/test-files/binary-$file_size-v2.bin"
555          
556          # Test operations
557          for operation in "create" "get" "restore"; do
558              echo -e "${BLUE}Testing versioning $operation with file size $file_size${NC}"
559              
560              # Run benchmark iterations
561              total_time=0
562              
563              for ((i=1; i<=ITERATIONS; i++)); do
564                  if [ "$QUIET_MODE" = false ]; then
565                      echo -e "${BLUE}Running iteration $i/${ITERATIONS}...${NC}"
566                  fi
567                  
568                  # Run the benchmark with time measurement
569                  start_time=$(date +%s.%N)
570                  
571                  case $operation in
572                      "create")
573                          # Simulate creating a version
574                          version_dir="$RESULTS_DIR/versions/v$i"
575                          mkdir -p "$version_dir"
576                          cp "$test_file" "$version_dir/original"
577                          ;;
578                      "get")
579                          # Simulate getting a version
580                          version_dir="$RESULTS_DIR/versions/v1"
581                          if [ -d "$version_dir" ]; then
582                              cp "$version_dir/original" "$RESULTS_DIR/test-files/retrieved-$i"
583                          else
584                              cp "$test_file" "$RESULTS_DIR/test-files/retrieved-$i"
585                          fi
586                          ;;
587                      "restore")
588                          # Simulate restoring a version
589                          version_dir="$RESULTS_DIR/versions/v1"
590                          if [ -d "$version_dir" ]; then
591                              cp "$version_dir/original" "$RESULTS_DIR/test-files/restored-$i"
592                          else
593                              cp "$test_file" "$RESULTS_DIR/test-files/restored-$i"
594                          fi
595                          ;;
596                  esac
597                  
598                  end_time=$(date +%s.%N)
599                  
600                  # Calculate time
601                  iteration_time=$(echo "$end_time - $start_time" | bc)
602                  total_time=$(echo "$total_time + $iteration_time" | bc)
603                  
604                  # Clean up
605                  if [ "$operation" = "get" ]; then
606                      rm -f "$RESULTS_DIR/test-files/retrieved-$i"
607                  elif [ "$operation" = "restore" ]; then
608                      rm -f "$RESULTS_DIR/test-files/restored-$i"
609                  fi
610                  
611                  if [ "$QUIET_MODE" = false ]; then
612                      echo -e "${BLUE}Iteration $i completed in ${iteration_time}s${NC}"
613                  fi
614              done
615              
616              # Calculate averages
617              avg_time=$(echo "scale=3; $total_time / $ITERATIONS" | bc)
618              
619              # Calculate throughput
620              file_size_bytes=$(size_to_bytes "$file_size")
621              throughput=$(echo "scale=2; $file_size_bytes / 1024 / 1024 / $avg_time" | bc)
622              
623              # Add to report
624              echo "| $file_size | $operation | $avg_time | $throughput |" >> "$REPORT_FILE"
625              
626              # Add to summary
627              echo "Versioning,$operation,$file_size,$avg_time,$throughput,N/A" >> "$SUMMARY_FILE"
628              
629              echo -e "${GREEN}Versioning $operation benchmark completed for file size $file_size${NC}"
630              echo -e "${GREEN}Average time: ${avg_time}s, Throughput: ${throughput} MB/s${NC}"
631          done
632      done
633      
634      # Clean up versioning directories
635      rm -rf "$RESULTS_DIR/versions"
636      
637      echo -e "${GREEN}Versioning benchmarks completed${NC}"
638  }
639  
640  # Function to generate summary
641  generate_summary() {
642      echo -e "${YELLOW}Generating summary...${NC}"
643      
644      # Process the summary file to generate statistics
645      cat >> "$REPORT_FILE" << EOF
646  
647  ## Performance Summary
648  
649  ### Best Throughput by Category
650  
651  EOF
652      
653      # Find best throughput for each category
654      for category in "AdaptiveChunking" "Encryption" "Compression" "Diff" "Versioning"; do
655          best_config=""
656          best_throughput=0
657          
658          while IFS=, read -r test config file_size avg_time throughput security; do
659              if [[ "$test" == "$category"* ]] && (( $(echo "$throughput > $best_throughput" | bc -l) )); then
660                  best_config="$config"
661                  best_throughput="$throughput"
662              fi
663          done < <(tail -n +2 "$SUMMARY_FILE")
664          
665          echo "- **$category**: $best_config - $best_throughput MB/s" >> "$REPORT_FILE"
666      done
667      
668      # Add security recommendations
669      cat >> "$REPORT_FILE" << EOF
670  
671  ### Security Recommendations
672  
673  Based on the benchmark results, the following configurations provide the best balance of performance and security:
674  
675  EOF
676      
677      # Find best security score with good throughput for encryption
678      best_config=""
679      best_score=0
680      min_throughput=10 # Minimum acceptable throughput in MB/s
681      
682      while IFS=, read -r test config file_size avg_time throughput security; do
683          if [[ "$test" == "Encryption"* ]] && [[ "$security" != "N/A" ]] && (( $(echo "$security > $best_score" | bc -l) )) && (( $(echo "$throughput >= $min_throughput" | bc -l) )); then
684              best_config="$config"
685              best_score="$security"
686          fi
687      done < <(tail -n +2 "$SUMMARY_FILE")
688      
689      echo "- **Encryption**: $best_config (Security Score: $best_score)" >> "$REPORT_FILE"
690      
691      # Find best chunk size for security
692      best_config=""
693      best_score=0
694      
695      while IFS=, read -r test config file_size avg_time throughput security; do
696          if [[ "$test" == "AdaptiveChunking"* ]] && [[ "$security" != "N/A" ]] && (( $(echo "$security > $best_score" | bc -l) )); then
697              best_config="$config"
698              best_score="$security"
699          fi
700      done < <(tail -n +2 "$SUMMARY_FILE")
701      
702      echo "- **Chunking**: $best_config (Security Score: $best_score)" >> "$REPORT_FILE"
703      
704      # Add adaptive chunking recommendations
705      cat >> "$REPORT_FILE" << EOF
706  
707  ### Adaptive Chunking Recommendations
708  
709  Based on the original code analysis and benchmark results, we recommend:
710  
711  - Small files (<10MB): Use 1MB chunks
712  - Medium files (10-100MB): Use 2MB chunks
713  - Large files (>100MB): Use 4MB chunks
714  - Maximum chunks per file: 1000 (to prevent excessive fragmentation)
715  - Transport layer chunk size: 5MB (larger than file chunks for efficient transfers)
716  
717  This adaptive approach provides the best balance of performance, security, and storage efficiency.
718  EOF
719      
720      echo -e "${GREEN}Summary generated successfully${NC}"
721  }
722  
723  # Main function
724  main() {
725      echo -e "${YELLOW}Starting KeepSync benchmark...${NC}"
726      
727      # Create test files
728      create_test_files
729      
730      # Run benchmarks
731      benchmark_adaptive_chunking
732      benchmark_encryption
733      benchmark_compression
734      benchmark_diff
735      benchmark_versioning
736      
737      # Generate summary
738      generate_summary
739      
740      echo -e "${GREEN}Benchmark completed successfully${NC}"
741      echo -e "${GREEN}Results saved to $RESULTS_DIR${NC}"
742      echo -e "${GREEN}Report: $REPORT_FILE${NC}"
743      echo -e "${GREEN}Summary: $SUMMARY_FILE${NC}"
744  }
745  
746  # Run the main function
747  main