Skip to content

Commit dc29fbb

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

File tree

2 files changed

+86
-1
lines changed

2 files changed

+86
-1
lines changed

bdb/cursor.c

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8720,12 +8720,86 @@ 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+
if (dbt_key.data)
8736+
free(dbt_key.data);
8737+
if (dbt_data.data)
8738+
free(dbt_data.data);
8739+
8740+
memset(&dbt_data, 0, sizeof(dbt_data));
8741+
dbt_data.data = &recnum;
8742+
dbt_data.ulen = sizeof(int);
8743+
dbt_data.flags |= DB_DBT_USERMEM;
8744+
rc = dbcp->c_get(dbcp, &dbt_key, &dbt_data, DB_GET_RECNO);
8745+
if (rc)
8746+
return rc;
8747+
*rnum = recnum;
8748+
return 0;
8749+
}
8750+
8751+
static int find_count_recnums(bdb_state_type *state, int64_t *rcnt)
8752+
{
8753+
int lowrecnum;
8754+
int highrecnum;
8755+
int rc;
8756+
DBC *dbcp;
8757+
if (!state->have_recnums)
8758+
return -1;
8759+
for (int i = 0; i < state->numix; i++) {
8760+
if (!state->ixrecnum[i])
8761+
continue;
8762+
rc = state->dbp_ix[i]->cursor(state->dbp_ix[i], 0, &dbcp, 0);
8763+
if (rc)
8764+
return rc;
8765+
if ((rc = find_recnum_first_last(dbcp, &lowrecnum, 0))) {
8766+
dbcp->c_close(dbcp);
8767+
return rc;
8768+
}
8769+
if ((rc = find_recnum_first_last(dbcp, &highrecnum, 1))) {
8770+
dbcp->c_close(dbcp);
8771+
return rc;
8772+
}
8773+
dbcp->c_close(dbcp);
8774+
*rcnt = highrecnum - lowrecnum + 1;
8775+
return 0;
8776+
}
8777+
return -1;
8778+
}
8779+
87238780
int bdb_direct_count_int(bdb_state_type *state, int ixnum, int64_t *rcnt, int parallel_count)
87248781
{
87258782
int64_t count = 0;
8783+
int rc = 0;
87268784
DB **db;
87278785
int stripes;
87288786
pthread_attr_t attr;
8787+
8788+
// first try recnums optimization
8789+
if (state->have_recnums) {
8790+
rc = find_count_recnums(state, &count);
8791+
if (rc == DB_LOCK_DEADLOCK) {
8792+
rc = BDBERR_DEADLOCK;
8793+
} else if (rc == DB_NOTFOUND) {
8794+
rc = 0;
8795+
} else if (rc != 0) {
8796+
rc = -1;
8797+
}
8798+
8799+
if (rc == 0) *rcnt = count;
8800+
return rc;
8801+
}
8802+
87298803
if (ixnum < 0) { // data
87308804
db = state->dbp_data[0];
87318805
stripes = state->attr->dtastripe;
@@ -8750,7 +8824,6 @@ int bdb_direct_count_int(bdb_state_type *state, int ixnum, int64_t *rcnt, int pa
87508824
db_count(&args[i]);
87518825
}
87528826
}
8753-
int rc = 0;
87548827
void *ret;
87558828
for (int i = 0; i < stripes; ++i) {
87568829
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)