Hình 19. Hoạt động của thuật tốn 1 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 mảnh dữ liệu ci có giá trị chunkID lớn nhất trong danh sách các chunk đang sở hữu*/
/**Chọn hàng xóm có khả năng chưa sở hữu 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 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
Nếu như trong giao thức kéo đẩy xen kẽ, máy tính trong một chu kỳ kéo hoặc đẩy của mình đưa ra quyết ñịnh chỉ dựa trên danh sách các mảnh dữ liệu hiện đang sở hữu tại máy tính đó, sau đó nó lựa chọn một hàng xóm để kéo hoặc ñẩy dữ liệu một cách ngẫu nhiên; thì trong các thuật tốn sửa đổi chúng tơi đề xuất tại mỗi máy tính sẽ
bổ sung lưu trữ một mảng chứa số tuần tự lớn nhất của các mảnh dữ liệu mà máy tính hàng xóm sở hữu đối với máy tính hiện tại. Sở dĩ chúng tơi dùng từ “đối với máy tính hiện tại” bởi lẽ số liệu của mảng dữ liệu này ñược xây dựng chỉ dựa trên việc thống kê sau các hoạt ñộng kéo hoặc ñẩy giữa máy tính hiện tại và máy tính hàng xóm. Do đó số tuần tự mảnh dữ liệu lớn nhất máy tính P lưu trữ cho máy tính N chưa chắc ñã là số tuần tự mảnh dữ liệu lớn nhất mà máy tính N đang thực sự sở hữu.
Cùng với việc bổ sung mảng push_maxID đó, chúng tơi cũng ñồng thời cải tiến cách thức ñưa ra quyết ñịnh của máy tính trong mạng.
Cụ thể, trong thuật tốn 1, trong chu kỳ kéo, máy tính vẫn giữ nguyên việc lựa chọn mảnh dữ liệu còn thiếu có số tuần tự nhỏ nhất. Nhưng khi lựa chọn hàng xóm, thay vì chọn một cách ngẫu nhiên như thuật tốn kéo đẩy xen kẽ gốc đề xuất, nó sẽ kiểm tra một vịng mảng push_maxID đang lưu trữ tại chính nó để tìm ra hàng xóm có khả năng chứa mảnh dữ liệu nó đang cần tìm kiếm là lớn nhất.
/**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()
Tương tự, trong chu kỳ ñẩy, máy tính cũng dựa trên mảng push_maxID đang lưu trữ tại chính nó để tìm ra hàng xóm có khả năng chưa có mảnh dữ liệu nó đang muốn ñẩy ñi là lớn nhất thay vì lựa chọn hàng xóm một cách ngẫu nhiên như giải thuật của giao thức kéo ñẩy xen kẽ nguyên bản:
/**Chọn mảnh dữ liệu ci có giá trị chunkID lớn nhất trong danh sách các chunk đang sở
hữu*/
/**Chọn hàng xóm có khả năng chưa sở hữu chunkID ci tìm thấy ở trên trường hợp để đẩy chunk ci sang. 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()