Hình 25. Hoạt động của thuật tốn 2 trong chu kỳ đẩy
Input: /**push_maxID: Mảng chứa giá trị chunkID lớn nhất của hàng xóm thứ i mà node hiện tại biết
được dựa trên các hoạt động kéo đẩy giữa node hiện tại với node hàng xóm đó
max_push_attempts: Số lần đẩy tối đa được phép max_pull_attempts: Số lần kéo tối đa được phép */
if (status == PULL) then
while (pull_attempt < max_pull_attempts) AND (download_bandwidth_available) do /**Chọn mảnh dữ liệu ci cịn thiếu có giá trị chunkID nhỏ nhất*/
/**Chọn hàng xóm có khả năng chứa chunkID ci tìm thấy ở trên. Trường hợp khơng thấy sẽ trả về hàng xóm ngẫu nhiên để tận dụng chu kỳ */
Node selectedNode = null; foreach (Node nei in contact_list)
if (push_maxID[nei.GetID()]>ci.GetID()) {
selectedNode = nei;
break; /* exit from the foreach cycle */ }
if (selectedNode == null)
selectedNode = getRNDNeighbor(); Send PULL message;
Wait for reply;
if (reply == ACCEPT PULL) then if (download_bandwidth_available) then {
Send READY message; startPullingPiece;
//Ghi nhận đã chuyển ci tới cho hàng xóm selectedNode if (push_maxID[selectedNode.GetID()]<ci.GetID()) {
push_maxID[selectedNode.GetID()] = ci.GetID(); }
break; /* exit from the while cycle */ }
else
Send BUSY message; end end pull_attempt++; end status = PUSH; pull_attempt = 0; end
if (status == PUSH) then
while (push_attempt < max_push_attempts) AND (upload_bandwidth_available) do /**Chọn hàng xóm ngẫu nhiên */
Node selectedNode = getRNDNeighbor();
/**Chọn mảnh dữ liệu ci có giá trị chunkID nhỏ nhất mà node hàng xóm selectedNode chưa sở hữu trong số các chunk mà node có. Trường hợp selectedNode đã có tất cả các chunk mà node hiện tại có thì sẽ bỏ trống chu kỳ */
Chunk selectedChunk = null;
foreach (Chunk ci in ChunkListOwned)
if (push_maxID[selectedNode.GetID()]<ci.GetID()) {
selectedChunk = ci;
break; /* exit from the foreach cycle */ }
if (selectedChunk != null) {
Send PUSH message; Wait for reply;
if (reply == ACCEPT PUSH) then
if (upload_bandwidth_available) then {
Send READY message; startPushingPiece;
//Ghi nhận đã chuyển ci tới cho hàng xóm selectedNode if (push_maxID[selectedNode.GetID()]<ci.GetID()) {
push_maxID[selectedNode.GetID()] = ci.GetID(); }
break; /* exit from the while cycle */ }else
Send BUSY message; end end push_attempt++; } end status = PULL; push_attempt = 0; end
Thuật tốn 2 có cài đặt một số sửa đổi nhỏ của thuật tốn 1 được đề xuất ở trên. Thay vì lựa chọn các máy tính hàng xóm sau khi đã lựa chọn mảnh dữ liệu ñể kéo về hoặc ñẩy ñi; máy tính sẽ lựa chọn ngẫu nhiên một hàng xóm trước, sau đó trên cơ sở hàng xóm được chọn ñó sẽ chọn trong số các mảnh dữ liệu nó sở hữu, một mảnh dữ liệu có số tuần tự nhỏ nhất mà hàng xóm đó có thể chưa có ñể ñẩy ñi. Lý do chính của việc cài ñặt này là nhằm giúp giảm độ trễ truyền thơng so với thuật tốn kéo đẩy xen kẽ ngun bản và thuật toán 1. Khi mà cả hai thuật toán kéo ñẩy xen kẽ nguyên bản và thuật tốn 1 ln lựa chọn các mảnh dữ liệu có số tuần tự lớn nhất trong các mảnh dữ liệu nó đang có.
/**Chọn hàng xóm ngẫu nhiên */
Node selectedNode = getRNDNeighbor();
/**Chọn mảnh dữ liệu ci có giá trị chunkID nhỏ nhất mà node hàng xóm selectedNode chưa sở hữu trong số các chunk mà node có. Trường hợp selectedNode đã có tất cả các chunk mà node hiện tại có thì sẽ bỏ trống chu kỳ */
Chunk selectedChunk = null;
foreach (Chunk ci in ChunkListOwned)
if (push_maxID[selectedNode.GetID()]<ci.GetID()) {
selectedChunk = ci;
break; /* exit from the foreach cycle */ }