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:
Jérôme Duval
2011-02-11 18:13:21 +00:00
parent 9fd5bdcbd4
commit e44c723193
2 changed files with 13 additions and 4 deletions
@@ -24,6 +24,7 @@
DataStream::DataStream(Volume* volume, Inode* inode, off_t size)
:
kBlockSize(volume->BlockSize()),
kClusterSize(volume->ClusterSize()),
fVolume(volume),
fInode(inode),
fSize(size)
@@ -44,8 +45,8 @@ DataStream::FindBlock(off_t pos, off_t& physical, off_t *_length)
TRACE("FindBlock: offset larger than size\n");
return B_ENTRY_NOT_FOUND;
}
cluster_t clusterIndex = pos / fVolume->ClusterSize();
uint32 offset = pos % fVolume->ClusterSize();
cluster_t clusterIndex = pos / kClusterSize;
uint32 offset = pos % kClusterSize;
cluster_t cluster = fInode->StartCluster();
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;
fVolume->ClusterToBlock(cluster, block);
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",
fInode->ID(), fInode->StartCluster(), pos, physical);
fInode->ID(), clusterIndex, pos, physical);
return B_OK;
}
@@ -27,6 +27,7 @@ public:
off_t *_length = NULL);
private:
const uint32 kBlockSize;
const uint32 kClusterSize;
Volume* fVolume;
Inode* fInode;
off_t fNumBlocks;