@@ -92,45 +92,43 @@ def group_packages(packages):
9292 package_weights .append ((pkg , weight ))
9393 total_weight += weight
9494
95- # Determine number of shards based on total weight
96- # 1. Base shard count on weight capacity of 10 per shard
97- num_shards = math .ceil (total_weight / 10 )
98-
99- # Ensure at least 1 shard if we have packages
100- num_shards = max (1 , num_shards )
101-
102- # 2. Top out at 16 shards
103- num_shards = min (16 , num_shards )
104-
105- # Initialize shards as empty lists of packages with their current total weight
106- shard_buckets = [{"packages" : [], "weight" : 0 } for _ in range (num_shards )]
107-
108- # Sort packages descending by weight (LPT heuristic)
109- # If weights are equal, sort alphabetically for stability
110- sorted_packages = sorted (package_weights , key = lambda x : (- x [1 ], x [0 ]))
95+ # Dynamically determine target weight to balance across max 16 shards.
96+ # 1. Base shard count has a target weight capacity of 10 per shard.
97+ # 2. To avoid exceeding 16 shards, we scale the target weight dynamically
98+ # based on the total workload.
99+ max_shards = 16
100+ target_weight = max (10 , math .ceil (total_weight / max_shards ))
101+
102+ shards_list = []
103+ current_shard_packages = []
104+ current_shard_weight = 0
105+
106+ # Pack packages alphabetically and contiguously.
107+ for pkg , weight in package_weights :
108+ # Check if adding this package would exceed the target weight
109+ if current_shard_packages and (current_shard_weight + weight > target_weight ):
110+ shards_list .append (current_shard_packages )
111+ current_shard_packages = [pkg ]
112+ current_shard_weight = weight
113+ else :
114+ current_shard_packages .append (pkg )
115+ current_shard_weight += weight
111116
112- # Distribute greedily to the bucket with the minimum current weight
113- for pkg , weight in sorted_packages :
114- min_bucket = min (shard_buckets , key = lambda b : b ["weight" ])
115- min_bucket ["packages" ].append (pkg )
116- min_bucket ["weight" ] += weight
117+ if current_shard_packages :
118+ shards_list .append (current_shard_packages )
117119
118120 # Construct the final shards output list
119121 shards = []
120- index = 1
121- for bucket in shard_buckets :
122- shard_packages = bucket ["packages" ]
123- if not shard_packages :
124- continue
122+ for i , shard_packages in enumerate (shards_list ):
123+ index = i + 1
125124 name = f"Shard { index } "
126125 num_in_shard = len (shard_packages )
127-
128- # Sort packages alphabetically for a cleaner description
129- sorted_shard_pkgs = sorted (shard_packages )
130- if len (sorted_shard_pkgs ) == 1 :
131- desc = sorted_shard_pkgs [0 ].strip ('/' ).split ('/' )[- 1 ]
126+
127+ # Calculate contiguous range description
128+ if len (shard_packages ) == 1 :
129+ desc = shard_packages [0 ].strip ('/' ).split ('/' )[- 1 ]
132130 else :
133- desc = f"{ sorted_shard_pkgs [0 ].strip ('/' ).split ('/' )[- 1 ]} ...{ sorted_shard_pkgs [- 1 ].strip ('/' ).split ('/' )[- 1 ]} ({ num_in_shard } packages)"
131+ desc = f"{ shard_packages [0 ].strip ('/' ).split ('/' )[- 1 ]} ...{ shard_packages [- 1 ].strip ('/' ).split ('/' )[- 1 ]} ({ num_in_shard } packages)"
134132
135133 shards .append ({
136134 "name" : name ,
@@ -139,7 +137,6 @@ def group_packages(packages):
139137 "packages" : " " .join (shard_packages ),
140138 "is_sharded" : True
141139 })
142- index += 1
143140
144141 # Set is_sharded dynamically based on the total number of shards
145142 total_shards = len (shards )
0 commit comments