UNPKG

ipfs-bitswap

Version:

JavaScript implementation of the Bitswap data exchange protocol used by IPFS

93 lines (83 loc) 3.17 kB
import type { Task } from './index.js' export const DefaultTaskMerger = { /** * Indicates whether the given task has newer information than the active * tasks with the same topic. * * @param {Task} task * @param {Task[]} tasksWithTopic * @returns {boolean} */ hasNewInfo (task: Task, tasksWithTopic: Task[]): boolean { let haveBlock = false let isWantBlock = false for (const existing of tasksWithTopic) { if (existing.data.haveBlock) { haveBlock = true } if (existing.data.isWantBlock) { isWantBlock = true } } // If there is no active want-block and the new task is a want-block, // the new task is better if (!isWantBlock && task.data.isWantBlock) { return true } // If we didn't have the block, and the new task indicates that we now // do have the block, then we must also have size information for the // block, so the new task has new information. if (!haveBlock && task.data.haveBlock) { return true } return false }, /** * Merge the information from the given task into the existing task (with the * same topic) */ merge (newTask: Task, existingTask: Task) { // The merge function ignores the topic and priority as these don't change. // // We may receive new information about a want before the want has been // popped from the queue in the following scenarios: // // - Replace want type: // 1. Client sends want-have CID1 // 2. Client sends want-block CID1 // In this case we should replace want-have with want-block, including // updating the task size to be the block size. // // - Replace DONT_HAVE with want: // 1. Client sends want-have CID1 or want-block CID1 // 2. Local node doesn't have block for CID1 // 3. Local node receives block for CID1 from peer // In this case we should replace DONT_HAVE with the want, including // updating the task size and block size. const taskData = newTask.data const existingData = existingTask.data // If we didn't have block size information (because we didn't have the // block) and we receive the block from a peer, update the task with the // new block size if (!existingData.haveBlock && taskData.haveBlock) { existingData.haveBlock = taskData.haveBlock existingData.blockSize = taskData.blockSize } // If replacing a want-have with a want-block if (!existingData.isWantBlock && taskData.isWantBlock) { // Change the type from want-have to want-block existingData.isWantBlock = true // If the want-have was a DONT_HAVE, or the want-block has a size if (!existingData.haveBlock || taskData.haveBlock) { // Update the entry size existingData.haveBlock = taskData.haveBlock existingTask.size = newTask.size } } // If the task is a want-block, make sure the entry size is equal // to the block size (because we will send the whole block) if (existingData.isWantBlock && existingData.haveBlock) { existingTask.size = existingData.blockSize } } }