1616/**
1717 * Memcached storage using memcached extension.
1818 */
19- class MemcachedStorage implements Nette\Caching\Storage, Nette\Caching\BulkReader
19+ class MemcachedStorage implements Nette\Caching\Storage, Nette\Caching\BulkReader, Nette\Caching\BulkWriter
2020{
2121 /** @internal cache structure */
2222 private const
@@ -25,8 +25,6 @@ class MemcachedStorage implements Nette\Caching\Storage, Nette\Caching\BulkReade
2525 MetaDelta = 'delta';
2626
2727 private \Memcached $memcached;
28- private string $prefix;
29- private ?Journal $journal;
3028
3129
3230 /**
@@ -41,15 +39,12 @@ public static function isAvailable(): bool
4139 public function __construct(
4240 string $host = 'localhost',
4341 int $port = 11211,
44- string $prefix = '',
45- ?Journal $journal = null,
42+ private string $prefix = '',
43+ private ?Journal $journal = null,
4644 ) {
4745 if (!static::isAvailable()) {
4846 throw new Nette\NotSupportedException("PHP extension 'memcached' is not loaded.");
4947 }
50-
51- $this->prefix = $prefix;
52- $this->journal = $journal;
5348 $this->memcached = new \Memcached;
5449 if ($host) {
5550 $this->addServer($host, $port);
@@ -168,12 +163,60 @@ public function write(string $key, $data, array $dp): void
168163 }
169164
170165
166+ public function bulkWrite(array $items, array $dp): bool
167+ {
168+ if (isset($dp[Cache::Items])) {
169+ throw new Nette\NotSupportedException('Dependent items are not supported by MemcachedStorage.');
170+ }
171+
172+ $records = [];
173+
174+ $expire = 0;
175+ if (isset($dp[Cache::Expire])) {
176+ $expire = (int) $dp[Cache::Expire];
177+ }
178+
179+ foreach ($items as $key => $data) {
180+ $key = urlencode($this->prefix . $key);
181+ $meta = [
182+ self::MetaData => $data,
183+ ];
184+
185+ if (!empty($dp[Cache::Sliding])) {
186+ $meta[self::MetaDelta] = $expire; // sliding time
187+ }
188+
189+ if (isset($dp[Cache::Callbacks])) {
190+ $meta[self::MetaCallbacks] = $dp[Cache::Callbacks];
191+ }
192+
193+ if (isset($dp[Cache::Tags]) || isset($dp[Cache::Priority])) {
194+ if (!$this->journal) {
195+ throw new Nette\InvalidStateException('CacheJournal has not been provided.');
196+ }
197+
198+ $this->journal->write($key, $dp);
199+ }
200+
201+ $records[$key] = $meta;
202+ }
203+
204+ return $this->memcached->setMulti($records, $expire);
205+ }
206+
207+
171208 public function remove(string $key): void
172209 {
173210 $this->memcached->delete(urlencode($this->prefix . $key), 0);
174211 }
175212
176213
214+ public function bulkRemove(array $keys): void
215+ {
216+ $this->memcached->deleteMulti(array_map(fn($key) => urlencode($this->prefix . $key), $keys), 0);
217+ }
218+
219+
177220 public function clean(array $conditions): void
178221 {
179222 if (!empty($conditions[Cache::All])) {
0 commit comments