#include "leveldb/db.h"
#include <iostream>

using namespace std;
using namespace leveldb;

int test1() {
  DB* db = nullptr;

  Options op;
  op.create_if_missing = true;
  Status status = DB::Open(op, "testdb1", &db);
  assert(status.ok());
  db->Put(WriteOptions(), "001", "leveldb");
  size_t s;
  db->get_slot_num(ReadOptions(), "001", &s);
  cout<<to_string(s)<<endl;
  cout << to_string(s).size() << endl;

  db->Put(WriteOptions(), "002", "world");
  string s1;
  db->Delete(WriteOptions(), "002"); // sc: {0, 33}
  db->Get(ReadOptions(), "002", &s1);
  cout << s1.size() << endl;
  cout<<s1<<endl;

  delete db;
  return 0;
}


int test2() {
  DB* db = nullptr;
  Options op;
  op.create_if_missing = true;
  Status status = DB::Open(op, "testdb2", &db);
  assert(status.ok());

  const std::string value_prefix = "value_";
  const size_t loop_times = 1000000;
  int k = 0;
  for (auto i = 0; i < loop_times; i++) {
    if (i == 220) {
      k ++;
    }
    auto key = std::to_string(i);
    auto value = value_prefix + key;
    db->Put(WriteOptions(), key, value);
    string s;
    db->Get(ReadOptions(), key, &s);
    cout << s << " | " << s.size() << endl;

  }

  cout << endl << "all put are done" << endl << endl;

  for (auto i = 0; i < loop_times; i++) {
    auto key = std::to_string(i);
    auto value = value_prefix + key;

//    db->Put(WriteOptions(), key, value+"_");
    string s1;
    db->Delete(WriteOptions(), key);  // sc: {0, 33}
    db->Get(ReadOptions(), key, &s1);
    cout << s1 << " | " << s1.size() << " | " << i << endl;
  }

  delete db;
  std::cout << "db has been deleted!" << std::endl;
  return 0;
}

int test3() {
  DB* db = nullptr;
  Options op;
  op.create_if_missing = true;
  Status status = DB::Open(op, "testdb2", &db);
  assert(status.ok());

  const std::string value_prefix = "value_";
  const size_t loop_times = 10;
  for (auto i = 0; i < loop_times; i++) {
    auto key = std::to_string(i);
    auto value = value_prefix + key;
    db->Put(WriteOptions(), key, value);
    string s;
    db->Get(ReadOptions(), key, &s);
    cout << s << " | " << s.size() << endl;

  }

//  cout << endl << "all put are done" << endl << endl;
//
//  for (auto i = 0; i < loop_times; i++) {
//    auto key = std::to_string(i);
//    auto value = value_prefix + key;
//
//    //    db->Put(WriteOptions(), key, value+"_");
//    string s1;
//    db->Delete(WriteOptions(), key);  // sc: {0, 33}
//    db->Get(ReadOptions(), key, &s1);
//    cout << s1 << " | " << s1.size() << " | " << i << endl;
//  }

  delete db;
  std::cout << "db has been deleted!" << std::endl;
  return 0;
}

int test4() {
  DB* db = nullptr;
  Options op;
  op.create_if_missing = true;
  Status status = DB::Open(op, "testdb2", &db);
  assert(status.ok());

  const std::string value_prefix = "value_";
  const size_t loop_times = 10;
//  for (auto i = 0; i < loop_times; i++) {
//    auto key = std::to_string(i);
//    auto value = value_prefix + key;
//    db->Put(WriteOptions(), key, value);
//    string s;
//    db->Get(ReadOptions(), key, &s);
//    cout << s << " | " << s.size() << endl;
//
//  }

//    cout << endl << "all put are done" << endl << endl;

    for (auto i = 0; i < loop_times; i++) {
      auto key = std::to_string(i);
      auto value = value_prefix + key;

      //    db->Put(WriteOptions(), key, value+"_");
      string s1;
      db->Delete(WriteOptions(), key);  // sc: {0, 33}
      db->Get(ReadOptions(), key, &s1);
      cout << s1 << " | " << s1.size() << " | " << i << endl;
    }

  delete db;
  std::cout << "db has been deleted!" << std::endl;
  return 0;
}


int main() {
//  test3();
//  std::cout << std::endl << std::endl;
//  test4();
test2();
}