Skip to content

Commit f14d489

Browse files
committed
pack shards alphabetically
1 parent 2e9bafc commit f14d489

1 file changed

Lines changed: 30 additions & 33 deletions

File tree

ci/get_package_shards.py

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)