83 lines
2.7 KiB
TypeScript
83 lines
2.7 KiB
TypeScript
/**
|
|
* 🚀 Chunk range calculation utilities
|
|
* Provides unified chunk calculation logic to ensure consistency between sender and receiver
|
|
*/
|
|
|
|
export class ChunkRangeCalculator {
|
|
/**
|
|
* Calculate chunk range for a file with given parameters
|
|
* This method ensures both sender and receiver use identical calculation logic
|
|
*/
|
|
static getChunkRange(fileSize: number, startOffset: number, chunkSize: number) {
|
|
// Calculate starting chunk index
|
|
const startChunk = Math.floor(startOffset / chunkSize);
|
|
|
|
// Calculate ending chunk index based on the last byte of the file
|
|
const lastByteIndex = fileSize - 1;
|
|
const endChunk = Math.floor(lastByteIndex / chunkSize);
|
|
|
|
// Calculate total chunks to be sent/received (from startChunk to endChunk inclusive)
|
|
const totalChunks = endChunk - startChunk + 1;
|
|
|
|
// Calculate absolute total chunks in the entire file
|
|
const absoluteTotalChunks = Math.ceil(fileSize / chunkSize);
|
|
|
|
return {
|
|
startChunk, // First chunk index to process
|
|
endChunk, // Last chunk index to process
|
|
totalChunks, // Number of chunks to process (for resume transfers)
|
|
absoluteTotalChunks // Total chunks in the entire file
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Calculate expected chunks count for resume transfer
|
|
* Identical to ReceptionConfig.calculateExpectedChunks()
|
|
*/
|
|
static calculateExpectedChunks(fileSize: number, startOffset: number, chunkSize: number): number {
|
|
return Math.ceil((fileSize - startOffset) / chunkSize);
|
|
}
|
|
|
|
/**
|
|
* Get chunk index from file offset
|
|
* Identical to ReceptionConfig.getChunkIndexFromOffset()
|
|
*/
|
|
static getChunkIndexFromOffset(offset: number, chunkSize: number): number {
|
|
return Math.floor(offset / chunkSize);
|
|
}
|
|
|
|
/**
|
|
* Get file offset from chunk index
|
|
* Identical to ReceptionConfig.getOffsetFromChunkIndex()
|
|
*/
|
|
static getOffsetFromChunkIndex(chunkIndex: number, chunkSize: number): number {
|
|
return chunkIndex * chunkSize;
|
|
}
|
|
|
|
/**
|
|
* Validate chunk index within expected range
|
|
*/
|
|
static isChunkIndexValid(
|
|
chunkIndex: number,
|
|
startOffset: number,
|
|
fileSize: number,
|
|
chunkSize: number
|
|
): boolean {
|
|
const range = this.getChunkRange(fileSize, startOffset, chunkSize);
|
|
return chunkIndex >= range.startChunk && chunkIndex <= range.endChunk;
|
|
}
|
|
|
|
/**
|
|
* Calculate relative chunk index from absolute chunk index
|
|
* Used by receiver to map sender's absolute index to local array index
|
|
*/
|
|
static getRelativeChunkIndex(
|
|
absoluteChunkIndex: number,
|
|
startOffset: number,
|
|
chunkSize: number
|
|
): number {
|
|
const startChunkIndex = this.getChunkIndexFromOffset(startOffset, chunkSize);
|
|
return absoluteChunkIndex - startChunkIndex;
|
|
}
|
|
}
|