Improved DataStream::FindBlock() to return big extents instead of single blocks. This really speeds up the get_file_map operation for big files.
Thanks to Stephan for reporting. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40440 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
DataStream::DataStream(Volume* volume, Inode* inode, off_t size)
|
DataStream::DataStream(Volume* volume, Inode* inode, off_t size)
|
||||||
:
|
:
|
||||||
kBlockSize(volume->BlockSize()),
|
kBlockSize(volume->BlockSize()),
|
||||||
|
kClusterSize(volume->ClusterSize()),
|
||||||
fVolume(volume),
|
fVolume(volume),
|
||||||
fInode(inode),
|
fInode(inode),
|
||||||
fSize(size)
|
fSize(size)
|
||||||
@@ -44,8 +45,8 @@ DataStream::FindBlock(off_t pos, off_t& physical, off_t *_length)
|
|||||||
TRACE("FindBlock: offset larger than size\n");
|
TRACE("FindBlock: offset larger than size\n");
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
cluster_t clusterIndex = pos / fVolume->ClusterSize();
|
cluster_t clusterIndex = pos / kClusterSize;
|
||||||
uint32 offset = pos % fVolume->ClusterSize();
|
uint32 offset = pos % kClusterSize;
|
||||||
|
|
||||||
cluster_t cluster = fInode->StartCluster();
|
cluster_t cluster = fInode->StartCluster();
|
||||||
for (uint32 i = 0; i < clusterIndex; i++)
|
for (uint32 i = 0; i < clusterIndex; i++)
|
||||||
@@ -53,9 +54,16 @@ DataStream::FindBlock(off_t pos, off_t& physical, off_t *_length)
|
|||||||
fsblock_t block;
|
fsblock_t block;
|
||||||
fVolume->ClusterToBlock(cluster, block);
|
fVolume->ClusterToBlock(cluster, block);
|
||||||
physical = block * kBlockSize + offset;
|
physical = block * kBlockSize + offset;
|
||||||
*_length = min_c(kBlockSize, fSize - pos);
|
for (uint32 i = 0; i < 64; i++) {
|
||||||
|
cluster_t extentEnd = fInode->NextCluster(cluster);
|
||||||
|
if (extentEnd == EXFAT_CLUSTER_END || extentEnd == cluster + 1)
|
||||||
|
break;
|
||||||
|
cluster = extentEnd;
|
||||||
|
}
|
||||||
|
*_length = min_c((cluster - clusterIndex + 1) * kClusterSize - offset,
|
||||||
|
fSize - pos);
|
||||||
TRACE("inode %" B_PRIdINO ": cluster %ld, pos %lld, %lld\n",
|
TRACE("inode %" B_PRIdINO ": cluster %ld, pos %lld, %lld\n",
|
||||||
fInode->ID(), fInode->StartCluster(), pos, physical);
|
fInode->ID(), clusterIndex, pos, physical);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public:
|
|||||||
off_t *_length = NULL);
|
off_t *_length = NULL);
|
||||||
private:
|
private:
|
||||||
const uint32 kBlockSize;
|
const uint32 kBlockSize;
|
||||||
|
const uint32 kClusterSize;
|
||||||
Volume* fVolume;
|
Volume* fVolume;
|
||||||
Inode* fInode;
|
Inode* fInode;
|
||||||
off_t fNumBlocks;
|
off_t fNumBlocks;
|
||||||
|
|||||||
Reference in New Issue
Block a user