CAMLprim value hh_get_sqlite()

in source/hack_parallel/hack_parallel/heap/hh_shared.c [2891:2949]


CAMLprim value hh_get_sqlite(value ocaml_key) {
  CAMLparam1(ocaml_key);
  CAMLlocal1(result);

  result = Val_none;

  assert(hashtable_db_filename != NULL);

  // Check whether we are in SQL mode
  if (*hashtable_db_filename == '\0') {
    // We are not in SQL mode, return empty list
    CAMLreturn(result);
  }

  // Now that we know we are in SQL mode, make sure db connection is made
  if (hashtable_db == NULL) {
    assert(*hashtable_db_filename != '\0');
    // We are in sql, hence we shouldn't be in the master process,
    // since we are not connected yet, soo.. try to connect
    assert_not_master();
    // SQLITE_OPEN_READONLY makes sure that we throw if the db doesn't exist
    assert_sql(
        sqlite3_open_v2(
            hashtable_db_filename, &hashtable_db, SQLITE_OPEN_READONLY, NULL),
        SQLITE_OK);
    assert(hashtable_db != NULL);
  }

  // The caller is required to pass a 32-bit node ID.
  const uint64_t hash = get_hash(ocaml_key);

  if (get_select_stmt == NULL) {
    const char* sql = "SELECT VALUE_VERTEX FROM HASHTABLE WHERE KEY_VERTEX=?;";
    assert_sql(
        sqlite3_prepare_v2(hashtable_db, sql, -1, &get_select_stmt, NULL),
        SQLITE_OK);
    assert(get_select_stmt != NULL);
  }

  assert_sql(sqlite3_bind_int64(get_select_stmt, 1, hash), SQLITE_OK);

  int err_num = sqlite3_step(get_select_stmt);
  // err_num is SQLITE_ROW if there is a row to look at,
  // SQLITE_DONE if no results
  if (err_num == SQLITE_ROW) {
    // Means we found it in the table
    // Columns are 0 indexed
    heap_entry_t* value =
        (heap_entry_t*)sqlite3_column_blob(get_select_stmt, 0);
    result = Val_some(hh_deserialize(value));
  } else if (err_num != SQLITE_DONE) {
    // Something went wrong in sqlite3_step, lets crash
    assert_sql(err_num, SQLITE_ROW);
  }

  assert_sql(sqlite3_clear_bindings(get_select_stmt), SQLITE_OK);
  assert_sql(sqlite3_reset(get_select_stmt), SQLITE_OK);
  CAMLreturn(result);
}