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