A year ago there was some discussion about the weakness of the current superseeding algorithm in Vuze. The implementation is 4-5 years old, and thus relatively old compared to other codebase.
http://forum.vuze.com/message.jspa?messageID=177745#177745
No (major) development on the superseeding code has been done after that, and so I spent a few hours trying to understand what the algorithm actually does.
The main logic, as I understand it:
1) masquerade as an empty peer, and go through pieces in numeric order and announce/assign them individually to peers one by one. When you reach last piece, go to normal seeding mode. For each piece a status number is maintained: Level 0 = unassigned, level 1 = assigned but incomplete, level 2 = complete (sent to someone), no other levels.
2) for selecting to which peer you upload next, keep track of how quickly the peers redistribute the piece they got from us (how long does it take for the piece to appear at a third peer?). for this purpose, when someone tells that he has a new piece (BT_HAVE or bitfield), check the tracking status of that piece. The responsible peer gets his "upload speed info" updated, when then piece appear somewhere. (The "upload speed info" is just time difference between end original sending of piece data and time of new observation.)
3) when there is time to announce/assign a piece, give it to the speediest free peer.
I tested with several torrents, where I was properly the only original seed, and evaluated the results.
Some observations and minor patches:
Both patches include some additional commenting in order to make the logic more understandable in future. The patches can be applied separately, as they touch separate parts of the logic.
1)
The first part is a rather simple algorithm, and offers rudimentary run-through of the pieces. However, the main problem is that there is no sophisticated housekeeping of the swarm status. If an early peer leaves/quits, he takes his "level 2" pieces with him, and others in the swarm may not yet have them. There is logic for returning the "assigned but incomplete" level 1 pieces to the pool (back to level 0) when a peer leaves, but as the pool is only gone through once from 0 to max piece, this gives no actual benefit.
I created a patch for PEPeerControlImpl.java, which uses
a local boolean variable to enable the re-run the pool from 0 to max.piece, when the end is reached for the first time. This enables small improvement to the logic, as those pieces which are known to be free/unallocated, get a second try. (Local variable is enough, as the goal is just to check if there are any level 0 pieces left when we reach the end. If there are, the counter gets set to the first found 0-level piece, and continues from there through pieces again.)
More full fix would be to evaluate availability of all pieces, when the last piece is reached (for the first time?). If peers have left the swarm and there are thus unavailable pieces although their level is 2, we would reallocate them to new peers on the second run.
2)
The idea to monitor peers' upload speed and use it for queue decision is also ok, but as far as I understand the source code, the implementation is faulty... Peer's upload/distribution speed info gets calculated each time when the piece appears somewhere. There is no status for "piece already seen as redistributed to a third-party". Thus each time when the piece appears somewhere, the original target peer gets his speed info punished by setting the speed (or actually slowness) to the slower value of current observation - original time, as if this was the first re-distribution of the piece. In practice this means, that the peers' speed info gets jumpy and does not reliably tell about the peer's recent upload speed of new pieces given to him.
I created a patch for SuperSeedPiece.java, which
creates a third status level = 3 to mark the piece as known to be redistributed. When the piece has been once seen at a third party, the original peer has thus redistributed the piece, and there is no need to pay attention for the piece in future. This stabilised the speed values of the good and quick peers by removing the punishment for them caused by repeated observations of the same piece getting distributed in the swarm.