Skip to content

Commit 7100c71

Browse files
Carl SchwanCarlSchwan
authored andcommitted
perf(metadata): Add optimized sharding for metadata deletion
Signed-off-by: Carl Schwan <carlschwan@kde.org>
1 parent fd38784 commit 7100c71

File tree

7 files changed

+45
-25
lines changed

7 files changed

+45
-25
lines changed

lib/private/Files/Cache/Cache.php

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -635,18 +635,32 @@ private function removeChildren(ICacheEntry $entry) {
635635
}
636636

637637
$cacheEntryRemovedEvents = [];
638-
foreach (array_combine($deletedIds, $deletedPaths) as $fileId => $filePath) {
639-
$cacheEntryRemovedEvent = new CacheEntryRemovedEvent(
640-
$this->storage,
641-
$filePath,
642-
$fileId,
643-
$this->getNumericStorageId()
644-
);
645-
$cacheEntryRemovedEvents[] = $cacheEntryRemovedEvent;
646-
$this->eventDispatcher->dispatchTyped($cacheEntryRemovedEvent);
647-
}
648-
$this->eventDispatcher->dispatchTyped(new CacheEntriesRemovedEvent($cacheEntryRemovedEvents));
638+
foreach (array_chunk(array_combine($deletedIds, $deletedPaths), 1000) as $chunk) {
639+
/** @var array<int, string> $chunk */
640+
foreach ($chunk as $fileId => $filePath) {
641+
$cacheEntryRemovedEvents[] = new CacheEntryRemovedEvent(
642+
$this->storage,
643+
$filePath,
644+
$fileId,
645+
$this->getNumericStorageId()
646+
);
647+
}
649648

649+
$exception = null;
650+
try {
651+
$this->eventDispatcher->dispatchTyped(new CacheEntriesRemovedEvent($cacheEntryRemovedEvents));
652+
} catch (\Exception $e) {
653+
// still send the other event
654+
$exception = $e;
655+
}
656+
foreach ($cacheEntryRemovedEvents as $cacheEntryRemovedEvent) {
657+
$this->eventDispatcher->dispatchTyped($cacheEntryRemovedEvent);
658+
}
659+
660+
if ($exception !== null) {
661+
throw $exception;
662+
}
663+
}
650664
}
651665

652666
/**

lib/private/FilesMetadata/FilesMetadataManager.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,9 @@ public function deleteMetadata(int $fileId): void {
214214
}
215215
}
216216

217-
public function deleteMetadataForFiles(array $fileIds): void {
217+
public function deleteMetadataForFiles(int $storage, array $fileIds): void {
218218
try {
219-
$this->metadataRequestService->dropMetadataForFiles($fileIds);
219+
$this->metadataRequestService->dropMetadataForFiles($storage, $fileIds);
220220
} catch (Exception $e) {
221221
$this->logger->warning('issue while deleteMetadata', ['exception' => $e, 'fileIds' => $fileIds]);
222222
}

lib/private/FilesMetadata/Listener/MetadataDelete.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,21 @@ public function handle(Event $event): void {
3333
}
3434

3535
$entries = $event->getCacheEntryRemovedEvents();
36-
$fileIds = [];
36+
$storageToFileIds = [];
3737

3838
foreach ($entries as $entry) {
3939
try {
40-
$fileIds[] = $entry->getFileId();
40+
$storageToFileIds[$entry->getStorageId()] ??= [];
41+
$storageToFileIds[$entry->getStorageId()][] = $entry->getFileId();
4142
} catch (Exception $e) {
4243
$this->logger->warning('issue while running MetadataDelete', ['exception' => $e]);
4344
}
4445
}
4546

4647
try {
47-
$this->filesMetadataManager->deleteMetadataForFiles($fileIds);
48+
foreach ($storageToFileIds as $storageId => $fileIds) {
49+
$this->filesMetadataManager->deleteMetadataForFiles($storageId, $fileIds);
50+
}
4851
} catch (Exception $e) {
4952
$this->logger->warning('issue while running MetadataDelete', ['exception' => $e]);
5053
}

lib/private/FilesMetadata/Service/MetadataRequestService.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,16 @@ public function dropMetadata(int $fileId): void {
147147

148148
/**
149149
* @param int[] $fileIds
150-
* @return void
151150
* @throws Exception
152151
*/
153-
public function dropMetadataForFiles(array $fileIds): void {
152+
public function dropMetadataForFiles(int $storage, array $fileIds): void {
154153
$chunks = array_chunk($fileIds, 1000);
155154

156155
foreach ($chunks as $chunk) {
157156
$qb = $this->dbConnection->getQueryBuilder();
158157
$qb->delete(self::TABLE_METADATA)
159-
->where($qb->expr()->in('file_id', $qb->createNamedParameter($fileIds, IQueryBuilder::PARAM_INT_ARRAY)));
158+
->where($qb->expr()->in('file_id', $qb->createNamedParameter($fileIds, IQueryBuilder::PARAM_INT_ARRAY)))
159+
->hintShardKey('storage', $storage);
160160
$qb->executeStatement();
161161
}
162162
}

lib/public/Files/Cache/CacheEntriesRemovedEvent.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,28 @@
88
*/
99
namespace OCP\Files\Cache;
1010

11+
use OCP\AppFramework\Attribute\Listenable;
1112
use OCP\EventDispatcher\Event;
1213

1314
/**
1415
* Meta-event wrapping multiple CacheEntryRemovedEvent for when an existing
1516
* entry in the cache gets removed.
1617
*
17-
* @since 32.0.0
18+
* @since 34.0.0
1819
*/
19-
#[\OCP\AppFramework\Attribute\Listenable(since: '32.0.0')]
20+
#[Listenable(since: '34.0.0')]
2021
class CacheEntriesRemovedEvent extends Event {
2122
/**
22-
* @param CacheEntryRemovedEvent[] $cacheEntryRemovedEvents
23+
* @param ICacheEvent[] $cacheEntryRemovedEvents
2324
*/
2425
public function __construct(
2526
private readonly array $cacheEntryRemovedEvents,
2627
) {
28+
Event::__construct();
2729
}
2830

2931
/**
30-
* @return CacheEntryRemovedEvent[]
32+
* @return ICacheEvent[]
3133
*/
3234
public function getCacheEntryRemovedEvents(): array {
3335
return $this->cacheEntryRemovedEvents;

lib/public/Files/Cache/CacheEntryRemovedEvent.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
/**
1212
* Event for when an existing entry in the cache gets removed
1313
*
14-
* Prefer using \c CacheEntriesRemovedEvent as it is more efficient when deleting
14+
* Prefer using CacheEntriesRemovedEvent as it is more efficient when deleting
1515
* multiple files at the same time.
1616
*
1717
* @since 21.0.0

lib/public/FilesMetadata/IFilesMetadataManager.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,12 @@ public function deleteMetadata(int $fileId): void;
103103
/**
104104
* Delete metadata and its indexes of multiple file ids
105105
*
106+
* @param int $storage The storage id coresponding to the $fileIds
106107
* @param array<int> $fileIds file ids
107108
* @return void
108109
* @since 32.0.0
109110
*/
110-
public function deleteMetadataForFiles(array $fileIds): void;
111+
public function deleteMetadataForFiles(int $storage, array $fileIds): void;
111112

112113
/**
113114
* generate and return a MetadataQuery to help building sql queries

0 commit comments

Comments
 (0)