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