Skip to content

Commit ee018db

Browse files
Merge pull request #1057 from nextcloud/cache-negative
perf: cache negative results in LockSerivice::getLockForNodeIds
2 parents 92476cb + 01fed36 commit ee018db

1 file changed

Lines changed: 25 additions & 8 deletions

File tree

lib/Service/LockService.php

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class LockService {
5555
private array $locks = [];
5656
private bool $lockRetrieved = false;
5757
private array $lockCache = [];
58+
private array $remoteLockCache = [];
5859
private ?array $directEditors = null;
5960
private bool $allowUserOverride = false;
6061

@@ -90,18 +91,26 @@ public function __construct(
9091
* @return FileLock|bool
9192
*/
9293
public function getLockForNodeId(int $nodeId, ?Node $node = null) {
93-
if (array_key_exists($nodeId, $this->lockCache) && $this->lockCache[$nodeId] !== null) {
94+
if (array_key_exists($nodeId, $this->lockCache) && $this->lockCache[$nodeId] !== false) {
9495
return $this->lockCache[$nodeId];
9596
}
9697

97-
try {
98-
$this->lockCache[$nodeId] = $this->getLockFromFileId($nodeId);
99-
} catch (LockNotFoundException) {
100-
$remoteLock = $this->getRemoteLockFromDav($nodeId, $node);
101-
$this->lockCache[$nodeId] = $remoteLock ?: false;
98+
if (array_key_exists($nodeId, $this->remoteLockCache)) {
99+
return $this->remoteLockCache[$nodeId];
100+
}
101+
102+
if (!array_key_exists($nodeId, $this->lockCache)) {
103+
try {
104+
$this->lockCache[$nodeId] = $this->getLockFromFileId($nodeId);
105+
return $this->lockCache[$nodeId];
106+
} catch (LockNotFoundException) {
107+
$this->lockCache[$nodeId] = false;
108+
}
102109
}
103110

104-
return $this->lockCache[$nodeId];
111+
$remoteLock = $this->getRemoteLockFromDav($nodeId, $node);
112+
$this->remoteLockCache[$nodeId] = $remoteLock ?: false;
113+
return $this->remoteLockCache[$nodeId];
105114
}
106115

107116
/**
@@ -113,8 +122,10 @@ public function getLockForNodeIds(array $nodeIds): array {
113122
$locks = [];
114123
$locksToRequest = [];
115124
foreach ($nodeIds as $nodeId) {
116-
if (array_key_exists($nodeId, $this->lockCache) && $this->lockCache[$nodeId] !== null) {
125+
if (array_key_exists($nodeId, $this->lockCache) && $this->lockCache[$nodeId] instanceof FileLock) {
117126
$locks[$nodeId] = $this->lockCache[$nodeId];
127+
} elseif (array_key_exists($nodeId, $this->remoteLockCache)) {
128+
$locks[$nodeId] = $this->remoteLockCache[$nodeId];
118129
} else {
119130
$locksToRequest[] = $nodeId;
120131
}
@@ -123,6 +134,12 @@ public function getLockForNodeIds(array $nodeIds): array {
123134
return $locks;
124135
}
125136

137+
// pre-fill the cache with negative hits for all requested ids
138+
// so if no lock is found for the file we store the negative hit
139+
foreach ($locksToRequest as $fileId) {
140+
$this->lockCache[$fileId] = false;
141+
}
142+
126143
$newLocks = [];
127144
while ($fileIds = array_splice($locksToRequest, 0, 1000)) {
128145
$newLocks[] = $this->locksRequest->getFromFileIds($fileIds);

0 commit comments

Comments
 (0)