Skip to content

Commit 5bed80a

Browse files
committed
Add recnum optimization to count code
Signed-off-by: Salil Chandra <schandra107@bloomberg.net>
1 parent 1a7b086 commit 5bed80a

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

bdb/cursor.c

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8720,12 +8720,92 @@ static void *db_count(void *varg)
87208720
return NULL;
87218721
}
87228722

8723+
static int find_recnum_first_last(DBC *dbcp, int *rnum, int last)
8724+
{
8725+
DBT dbt_key, dbt_data;
8726+
int recnum;
8727+
int rc;
8728+
memset(&dbt_key, 0, sizeof(dbt_key));
8729+
memset(&dbt_data, 0, sizeof(dbt_data));
8730+
dbt_key.flags |= DB_DBT_MALLOC;
8731+
dbt_data.flags |= DB_DBT_MALLOC;
8732+
rc = dbcp->c_get(dbcp, &dbt_key, &dbt_data, last ? DB_LAST : DB_FIRST);
8733+
if (rc)
8734+
return rc;
8735+
rc = comdb2_sql_tick();
8736+
if (rc)
8737+
return rc;
8738+
if (dbt_key.data)
8739+
free(dbt_key.data);
8740+
if (dbt_data.data)
8741+
free(dbt_data.data);
8742+
8743+
memset(&dbt_data, 0, sizeof(dbt_data));
8744+
dbt_data.data = &recnum;
8745+
dbt_data.ulen = sizeof(int);
8746+
dbt_data.flags |= DB_DBT_USERMEM;
8747+
rc = dbcp->c_get(dbcp, &dbt_key, &dbt_data, DB_GET_RECNO);
8748+
if (rc)
8749+
return rc;
8750+
rc = comdb2_sql_tick();
8751+
if (rc)
8752+
return rc;
8753+
*rnum = recnum;
8754+
return 0;
8755+
}
8756+
8757+
static int find_count_recnums(bdb_state_type *state, int64_t *rcnt)
8758+
{
8759+
int lowrecnum;
8760+
int highrecnum;
8761+
int rc;
8762+
DBC *dbcp;
8763+
if (!state->have_recnums)
8764+
return -1;
8765+
for (int i = 0; i < state->numix; i++) {
8766+
if (!state->ixrecnum[i])
8767+
continue;
8768+
rc = state->dbp_ix[i]->cursor(state->dbp_ix[i], 0, &dbcp, 0);
8769+
if (rc)
8770+
return rc;
8771+
if ((rc = find_recnum_first_last(dbcp, &lowrecnum, 0))) {
8772+
dbcp->c_close(dbcp);
8773+
return rc;
8774+
}
8775+
if ((rc = find_recnum_first_last(dbcp, &highrecnum, 1))) {
8776+
dbcp->c_close(dbcp);
8777+
return rc;
8778+
}
8779+
dbcp->c_close(dbcp);
8780+
*rcnt = highrecnum - lowrecnum + 1;
8781+
return 0;
8782+
}
8783+
return -1;
8784+
}
8785+
87238786
int bdb_direct_count_int(bdb_state_type *state, int ixnum, int64_t *rcnt, int parallel_count)
87248787
{
87258788
int64_t count = 0;
8789+
int rc = 0;
87268790
DB **db;
87278791
int stripes;
87288792
pthread_attr_t attr;
8793+
8794+
// first try recnums optimization
8795+
if (state->have_recnums) {
8796+
rc = find_count_recnums(state, &count);
8797+
if (rc == DB_LOCK_DEADLOCK) {
8798+
rc = BDBERR_DEADLOCK;
8799+
} else if (rc == DB_NOTFOUND) {
8800+
rc = 0;
8801+
} else if (rc != 0) {
8802+
rc = -1;
8803+
}
8804+
8805+
if (rc == 0) *rcnt = count;
8806+
return rc;
8807+
}
8808+
87298809
if (ixnum < 0) { // data
87308810
db = state->dbp_data[0];
87318811
stripes = state->attr->dtastripe;
@@ -8750,7 +8830,6 @@ int bdb_direct_count_int(bdb_state_type *state, int ixnum, int64_t *rcnt, int pa
87508830
db_count(&args[i]);
87518831
}
87528832
}
8753-
int rc = 0;
87548833
void *ret;
87558834
for (int i = 0; i < stripes; ++i) {
87568835
if (parallel_count) {

tests/recnum.test/runit

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,16 @@ if [[ $leaked_pages -lt 0 ]]; then
3636
cat out.res
3737
exit 1
3838
fi
39+
count=$(cdb2sql --tabs ${CDB2_OPTIONS} $dbnm default "select count(*) from t")
40+
if [[ $count != 10000 ]]; then
41+
echo "Expected count 10000, got count $count"
42+
exit 1
43+
fi
44+
45+
cdb2sql --tabs ${CDB2_OPTIONS} $dbnm default "truncate t"
46+
count=$(cdb2sql --tabs ${CDB2_OPTIONS} $dbnm default "select count(*) from t")
47+
if [[ $count != 0 ]]; then
48+
echo "Expected count 0, got count $count"
49+
exit 1
50+
fi
3951
exit 0

0 commit comments

Comments
 (0)