@@ -413,6 +413,8 @@ typedef struct {
413413 int count ;
414414 int capacity ;
415415 int max_files ;
416+ size_t max_total_bytes ;
417+ size_t total_bytes ;
416418 uint64_t deadline_ms ;
417419 bool count_only ;
418420 bool collect_excluded ;
@@ -504,8 +506,15 @@ static void fl_add(file_list_t *fl, const char *abs_path, const char *rel_path,
504506 fl -> limit_exceeded = true;
505507 return ;
506508 }
509+ size_t measured_size = size > 0 ? (size_t )size : 0 ;
510+ if (fl -> count_only && (fl -> total_bytes > fl -> max_total_bytes ||
511+ measured_size > fl -> max_total_bytes - fl -> total_bytes )) {
512+ fl -> limit_exceeded = true;
513+ return ;
514+ }
507515 if (fl -> count_only ) {
508516 fl -> count ++ ;
517+ fl -> total_bytes += measured_size ;
509518 return ;
510519 }
511520 if (fl -> count >= fl -> capacity ) {
@@ -1117,7 +1126,8 @@ static cbm_discover_status_t discover_impl(const char *repo_path, const cbm_disc
11171126 int * excluded_count_out ,
11181127 cbm_ignored_file_t * * ignored_out , int * ignored_count_out ,
11191128 int * ignored_total_out , bool count_only , int max_files ,
1120- uint64_t deadline_ms ) {
1129+ size_t max_total_bytes , uint64_t deadline_ms ,
1130+ size_t * total_bytes_out ) {
11211131 if (excluded_out ) {
11221132 * excluded_out = NULL ;
11231133 }
@@ -1133,6 +1143,9 @@ static cbm_discover_status_t discover_impl(const char *repo_path, const cbm_disc
11331143 if (ignored_total_out ) {
11341144 * ignored_total_out = 0 ;
11351145 }
1146+ if (total_bytes_out ) {
1147+ * total_bytes_out = 0 ;
1148+ }
11361149 if (!repo_path || !out || !count || (count_only && max_files < 0 )) {
11371150 return CBM_DISCOVER_ERROR ;
11381151 }
@@ -1206,6 +1219,7 @@ static cbm_discover_status_t discover_impl(const char *repo_path, const cbm_disc
12061219 /* Walk */
12071220 file_list_t fl = {
12081221 .max_files = count_only ? max_files : -1 ,
1222+ .max_total_bytes = count_only ? max_total_bytes : SIZE_MAX ,
12091223 .deadline_ms = count_only ? deadline_ms : 0 ,
12101224 .count_only = count_only ,
12111225 .collect_excluded = !count_only && excluded_out != NULL ,
@@ -1224,6 +1238,9 @@ static cbm_discover_status_t discover_impl(const char *repo_path, const cbm_disc
12241238 cbm_discover_free_excluded (fl .excluded , fl .excluded_count );
12251239 cbm_discover_free_ignored (fl .ignored , fl .ignored_count );
12261240 * count = fl .count ;
1241+ if (total_bytes_out ) {
1242+ * total_bytes_out = fl .total_bytes ;
1243+ }
12271244 if (fl .failed ) {
12281245 return CBM_DISCOVER_ERROR ;
12291246 }
@@ -1269,7 +1286,7 @@ int cbm_discover_ex2(const char *repo_path, const cbm_discover_opts_t *opts, cbm
12691286 cbm_ignored_file_t * * ignored_out , int * ignored_count_out ,
12701287 int * ignored_total_out ) {
12711288 return discover_impl (repo_path , opts , out , count , excluded_out , excluded_count_out , ignored_out ,
1272- ignored_count_out , ignored_total_out , false, 0 , 0 );
1289+ ignored_count_out , ignored_total_out , false, 0 , SIZE_MAX , 0 , NULL );
12731290}
12741291
12751292cbm_discover_status_t cbm_discover_count_bounded (const char * repo_path ,
@@ -1283,10 +1300,36 @@ cbm_discover_status_t cbm_discover_count_bounded(const char *repo_path,
12831300 }
12841301 cbm_file_info_t * files = NULL ;
12851302 int count = 0 ;
1286- cbm_discover_status_t status = discover_impl (repo_path , opts , & files , & count , NULL , NULL , NULL ,
1287- NULL , NULL , true, max_files , deadline_ms );
1303+ cbm_discover_status_t status =
1304+ discover_impl (repo_path , opts , & files , & count , NULL , NULL , NULL , NULL , NULL , true,
1305+ max_files , SIZE_MAX , deadline_ms , NULL );
1306+ cbm_discover_free (files , count );
1307+ * count_out = status == CBM_DISCOVER_ERROR ? -1 : count ;
1308+ return status ;
1309+ }
1310+
1311+ cbm_discover_status_t cbm_discover_measure_bounded (const char * repo_path ,
1312+ const cbm_discover_opts_t * opts , int max_files ,
1313+ size_t max_total_bytes , uint64_t deadline_ms ,
1314+ int * count_out , size_t * total_bytes_out ) {
1315+ if (count_out ) {
1316+ * count_out = -1 ;
1317+ }
1318+ if (total_bytes_out ) {
1319+ * total_bytes_out = 0 ;
1320+ }
1321+ if (!repo_path || !count_out || !total_bytes_out || max_files < 0 ) {
1322+ return CBM_DISCOVER_ERROR ;
1323+ }
1324+ cbm_file_info_t * files = NULL ;
1325+ int count = 0 ;
1326+ size_t total_bytes = 0 ;
1327+ cbm_discover_status_t status =
1328+ discover_impl (repo_path , opts , & files , & count , NULL , NULL , NULL , NULL , NULL , true,
1329+ max_files , max_total_bytes , deadline_ms , & total_bytes );
12881330 cbm_discover_free (files , count );
12891331 * count_out = status == CBM_DISCOVER_ERROR ? -1 : count ;
1332+ * total_bytes_out = total_bytes ;
12901333 return status ;
12911334}
12921335
0 commit comments