export interface Shard {
    weight: number;
}
/**
 * Accepts a list of islands (an island is a collection of shards with different
 * weights). Modifies it to make the shards being distributed more fairly.
 * Returns the list of shards moves.
 *
 * ChatGPT mentions several related academical problems:
 * - "linear partitioning"
 * - "balanced partition"
 * - "partition problem"
 *
 * Unfortunately, none of the above approaches works out of the box due to
 * corner cases and heuristics we have.
 *
 * The current algorithm implemented is not perfect intentionally: it doesn't
 * try to achieve a fully-fair distribution, because it would produce way too
 * many moves otherwise (shards moves are expensive). Instead, it makes
 * trade-offs:
 * 1. Tries to unload the largest "overloaded" shards to the smallest island if
 *    such island wouldn't appear overloaded after that.
 * 2. If there is no such island in (1) (i.e. no matter where we move it, the
 *    destination will be overloaded), it may still move the shard to the
 *    smallest island, BUT only it the final benefit of the move would be more
 *    than SHARD_WEIGHT_MOVE_FROM_OVERLOADED_TO_OVERLOADED_FACTOR fraction of
 *    the shard's weight. (We don't want to pay the price for a move which won't
 *    move the needle much.)
 * 3. Compensates large shards relocations with the corresponding number of
 *    small shard relocations, so largest shards and smallest shards are
 *    redistributed more or less in sync with each other, and there will be e.g.
 *    no island with just 2 biggest shards, whilst other islands have tens of
 *    them.
 * 4. Also, a special treatment is applied to "empty" shards. They are treated
 *    as "filled in the future". The shard is considered "empty" if its weight
 *    is less than fractionOfMedianToConsiderEmpty of a median shard's weight.
 *    Such shards are distributed uniformly among the islands, not looking at
 *    their weights; this prevents the situation when most of the "empty" shards
 *    appear on the same island in the end.
 *
 * All those trade-offs produce a slightly imbalanced result. In real life, it
 * doesn't matter much though, because shards sizes are more or less equal.
 */
export declare function rebalance<TShard extends Shard>(islands: Map<number, readonly TShard[]>, decommissionIslandNos?: number[], fractionOfMedianToConsiderEmpty?: number): Array<{
    from: number;
    to: number;
    shards: TShard[];
}>;
//# sourceMappingURL=rebalance.d.ts.map