Skip to content

Commit 995d6c5

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

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
@@ -7454,12 +7454,86 @@ static void *db_count(void *varg)
74547454
return NULL;
74557455
}
74567456

7457+
static int find_recnum_first_last(DBC *dbcp, int *rnum, int last)
7458+
{
7459+
DBT dbt_key, dbt_data;
7460+
int recnum;
7461+
int rc;
7462+
memset(&dbt_key, 0, sizeof(dbt_key));
7463+
memset(&dbt_data, 0, sizeof(dbt_data));
7464+
dbt_key.flags |= DB_DBT_MALLOC;
7465+
dbt_data.flags |= DB_DBT_MALLOC;
7466+
rc = dbcp->c_get(dbcp, &dbt_key, &dbt_data, last ? DB_LAST : DB_FIRST);
7467+
if (rc)
7468+
return rc;
7469+
if (dbt_key.data)
7470+
free(dbt_key.data);
7471+
if (dbt_data.data)
7472+
free(dbt_data.data);
7473+
7474+
memset(&dbt_data, 0, sizeof(dbt_data));
7475+
dbt_data.data = &recnum;
7476+
dbt_data.ulen = sizeof(int);
7477+
dbt_data.flags |= DB_DBT_USERMEM;
7478+
rc = dbcp->c_get(dbcp, &dbt_key, &dbt_data, DB_GET_RECNO);
7479+
if (rc)
7480+
return rc;
7481+
*rnum = recnum;
7482+
return 0;
7483+
}
7484+
7485+
static int find_count_recnums(bdb_state_type *state, int64_t *rcnt)
7486+
{
7487+
int lowrecnum;
7488+
int highrecnum;
7489+
int rc;
7490+
DBC *dbcp;
7491+
if (!state->have_recnums)
7492+
return -1;
7493+
for (int i = 0; i < state->numix; i++) {
7494+
if (!state->ixrecnum[i])
7495+
continue;
7496+
rc = state->dbp_ix[i]->cursor(state->dbp_ix[i], 0, &dbcp, 0);
7497+
if (rc)
7498+
return rc;
7499+
if ((rc = find_recnum_first_last(dbcp, &lowrecnum, 0))) {
7500+
dbcp->c_close(dbcp);
7501+
return rc;
7502+
}
7503+
if ((rc = find_recnum_first_last(dbcp, &highrecnum, 1))) {
7504+
dbcp->c_close(dbcp);
7505+
return rc;
7506+
}
7507+
dbcp->c_close(dbcp);
7508+
*rcnt = highrecnum - lowrecnum + 1;
7509+
return 0;
7510+
}
7511+
return -1;
7512+
}
7513+
74577514
int bdb_direct_count_int(bdb_state_type *state, int ixnum, int64_t *rcnt, int is_snapcur, uint32_t modsnap_start_lsn_file, uint32_t modsnap_start_lsn_offset, uint32_t last_checkpoint_lsn_file, uint32_t last_checkpoint_lsn_offset, int parallel_count)
74587515
{
74597516
int64_t count = 0;
7517+
int rc = 0;
74607518
DB **db;
74617519
int stripes;
74627520
pthread_attr_t attr;
7521+
7522+
// first try recnums optimization
7523+
if (state->have_recnums) {
7524+
rc = find_count_recnums(state, &count);
7525+
if (rc == DB_LOCK_DEADLOCK) {
7526+
rc = BDBERR_DEADLOCK;
7527+
} else if (rc == DB_NOTFOUND) {
7528+
rc = 0;
7529+
} else if (rc != 0) {
7530+
rc = -1;
7531+
}
7532+
7533+
if (rc == 0) *rcnt = count;
7534+
return rc;
7535+
}
7536+
74637537
if (ixnum < 0) { // data
74647538
db = state->dbp_data[0];
74657539
stripes = state->attr->dtastripe;
@@ -7489,7 +7563,6 @@ int bdb_direct_count_int(bdb_state_type *state, int ixnum, int64_t *rcnt, int is
74897563
db_count(&args[i]);
74907564
}
74917565
}
7492-
int rc = 0;
74937566
void *ret;
74947567
for (int i = 0; i < stripes; ++i) {
74957568
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)