* The block cache now sorts the blocks before synchronizing a transaction.

* This should speed up writing a transaction considerably.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23694 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-01-21 20:34:06 +00:00
parent edadb083be
commit 5af13da19d
+41 -2
View File
@@ -275,6 +275,20 @@ lookup_transaction(block_cache *cache, int32 id)
// #pragma mark - cached_block
int
compare_blocks(const void *_blockA, const void *_blockB)
{
cached_block *blockA = (cached_block *)_blockA;
cached_block *blockB = (cached_block *)_blockB;
off_t diff = blockA->block_number - blockB->block_number;
if (diff > 0)
return 1;
return diff < 0 ? -1 : 0;
}
/* static */
int
cached_block::Compare(void *_cacheEntry, const void *_block)
@@ -1145,8 +1159,33 @@ cache_sync_transaction(void *_cache, int32 id)
// write back all of their remaining dirty blocks
T(Action("sync", cache, transaction));
while (transaction->num_blocks > 0) {
status = write_cached_block(cache, transaction->blocks.Head(),
false);
// sort blocks to speed up writing them back
// TODO: ideally, this should be handled by the I/O scheduler
block_list::Iterator iterator = transaction->blocks.GetIterator();
uint32 maxCount = transaction->num_blocks;
cached_block *buffer[16];
cached_block **blocks = (cached_block **)malloc(maxCount
* sizeof(void *));
if (blocks == NULL) {
maxCount = 16;
blocks = buffer;
}
uint32 count = 0;
for (; count < maxCount && iterator.HasNext(); count++) {
blocks[count] = iterator.Next();
}
qsort(blocks, count, sizeof(void *), &compare_blocks);
for (uint32 i = 0; i < count; i++) {
status = write_cached_block(cache, blocks[i], false);
if (status != B_OK)
break;
}
if (blocks != buffer)
free(blocks);
if (status != B_OK)
return status;
}