@@ -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+
74577514int 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 ) {
0 commit comments