//
// Created by 马也驰 on 2024/12/20.
//

#include <algorithm>
#include <thread>

#include "../db/slotpage.h"

#define SLOTNUM 8192

void printVector(const std::vector<size_t>& vec) {
  for (size_t i = 0; i < vec.size(); ++i) {
    std::cout << vec[i] << " ";
  }
  std::cout << std::endl;
}

int test1() {
  BitMap bitmap("test");
  std::vector<size_t> slots;
  slots.reserve(SLOTNUM<<2);
  int i = 0;
  for (i = 0; i < 2047; i++) {
    slots.push_back(bitmap.alloc_slot());
  }
  slots.push_back(bitmap.alloc_slot());
  for (; i < SLOTNUM<<2; i++) {
    slots.push_back(bitmap.alloc_slot());
  }
  printVector(slots);

  std::cout << "\n\n";

  for (i = 0; i < 100; i++) {
    bitmap.dealloc_slot(slots.at(i));
  }
  bitmap.dealloc_slot(10000);
  bitmap.dealloc_slot(11000);
  bitmap.dealloc_slot(12000);

  bitmap.show_allocated_slot();

  std::cout << "\n\n";

  for (i = 0; i < 103; i++) {
    bitmap.alloc_slot();
  }

  bitmap.show_allocated_slot();
  return 1;
}


int test2() {
  BitMap bitmap("test");
  std::vector<size_t> slots;
  slots.reserve(SLOTNUM);
  for (auto i = 0; i < SLOTNUM; i++) {
    slots.push_back(bitmap.alloc_slot());
  }
  printVector(slots);

  std::cout << "\n\n";

  bitmap.dealloc_slot(30);
  bitmap.dealloc_slot(40);
  bitmap.dealloc_slot(50);

  bitmap.show_allocated_slot();

  std::cout << "\n\n";

  bitmap.alloc_slot();
  bitmap.alloc_slot();

  bitmap.show_allocated_slot();
  return 1;
}

void allocate_slots(BitMap& bitmap, std::vector<size_t>& slots, int num_slots) {
  for (int i = 0; i < num_slots; i++) {
    slots.push_back(bitmap.alloc_slot());
  }
}

int test3() {
  BitMap bitmap("db");

  std::vector<size_t> slots1;
  slots1.reserve(1000);

  std::vector<size_t> slots2;
  slots2.reserve(1000);

  // Create two threads to allocate slots concurrently.
  std::thread thread1(allocate_slots, std::ref(bitmap), std::ref(slots1), 1000);
  std::thread thread2(allocate_slots, std::ref(bitmap), std::ref(slots2), 1000);

  // Wait for both threads to finish.
  thread1.join();
  thread2.join();

  // Print the results.
  std::cout << "Slots allocated by thread 1:\n";
  printVector(slots1);

  std::cout << "\n\nSlots allocated by thread 2:\n";
  printVector(slots2);

  std::cout << "\n\n";

  std::vector<size_t> combined_slots = slots1;
  combined_slots.insert(combined_slots.end(), slots2.begin(), slots2.end());
  std::sort(combined_slots.begin(), combined_slots.end());

  // Print the sorted combined slots.
  std::cout << "Sorted combined slots:\n";
  printVector(combined_slots);

  std::cout << "\n\n";


  return 1;
}

int main() {
  test3(); // 有问题
}