CAMLprim value hh_save_table_keys_sqlite()

in source/hack_parallel/hack_parallel/heap/hh_shared.c [2792:2852]


CAMLprim value hh_save_table_keys_sqlite(value out_filename, value keys) {
  CAMLparam2(out_filename, keys);

  assert_master();

  struct timeval tv = {0};
  struct timeval tv2 = {0};
  gettimeofday(&tv, NULL);

  sqlite3* db_out = NULL;
  assert_sql(sqlite3_open(String_val(out_filename), &db_out), SQLITE_OK);
  make_all_tables(db_out);
  write_sqlite_header(db_out, BuildInfo_kRevision);

  const char* sql =
      "CREATE TABLE IF NOT EXISTS HASHTABLE("
      "  KEY_VERTEX INT PRIMARY KEY NOT NULL,"
      "  VALUE_VERTEX BLOB NOT NULL"
      ");";
  assert_sql(sqlite3_exec(db_out, sql, NULL, 0, NULL), SQLITE_OK);

  assert_sql(
      sqlite3_exec(db_out, "PRAGMA synchronous = OFF", NULL, 0, NULL),
      SQLITE_OK);
  assert_sql(
      sqlite3_exec(db_out, "PRAGMA journal_mode = MEMORY", NULL, 0, NULL),
      SQLITE_OK);
  assert_sql(
      sqlite3_exec(db_out, "BEGIN TRANSACTION", NULL, 0, NULL), SQLITE_OK);

  sqlite3_stmt* insert_stmt = NULL;
  sql = "INSERT INTO HASHTABLE (KEY_VERTEX, VALUE_VERTEX) VALUES (?,?)";
  assert_sql(
      sqlite3_prepare_v2(db_out, sql, -1, &insert_stmt, NULL), SQLITE_OK);
  int n_keys = Wosize_val(keys);
  for (int i = 0; i < n_keys; ++i) {
    unsigned int slot = find_slot(Field(keys, i));
    uint64_t slot_hash = hashtbl[slot].hash;
    if (slot_hash == 0 || hashtbl[slot].addr == NULL) {
      continue;
    }
    char* value = hashtbl[slot].addr->data;
    size_t value_size = Heap_entry_total_size(hashtbl[slot].addr->header);

    assert_sql(sqlite3_bind_int64(insert_stmt, 1, slot_hash), SQLITE_OK);
    assert_sql(
        sqlite3_bind_blob(insert_stmt, 2, value, value_size, SQLITE_TRANSIENT),
        SQLITE_OK);
    assert_sql(sqlite3_step(insert_stmt), SQLITE_DONE);
    assert_sql(sqlite3_clear_bindings(insert_stmt), SQLITE_OK);
    assert_sql(sqlite3_reset(insert_stmt), SQLITE_OK);
  }

  assert_sql(sqlite3_finalize(insert_stmt), SQLITE_OK);
  assert_sql(sqlite3_exec(db_out, "END TRANSACTION", NULL, 0, NULL), SQLITE_OK);

  assert_sql(sqlite3_close(db_out), SQLITE_OK);
  gettimeofday(&tv2, NULL);
  int secs = tv2.tv_sec - tv.tv_sec;
  CAMLreturn(Val_long(secs));
}