Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
cacheenginexcache.php
1<?php
2namespace Bitrix\Main\Data;
3
4
6
8 implements ICacheEngine, ICacheEngineStat, LocalStorage\Storage\CacheEngineInterface
9{
10 private $sid = "BX";
11 //cache stats
12 private $written = false;
13 private $read = false;
14
15 protected $useLock = false;
16 protected $ttlMultiplier = 2;
17 protected static $locks = array();
18
23 function __construct($options = [])
24 {
25 $config = \Bitrix\Main\Config\Configuration::getValue("cache");
26
27 if ($config && is_array($config))
28 {
29 if (isset($config["use_lock"]))
30 {
31 $this->useLock = (bool)$config["use_lock"];
32 }
33
34 if (isset($config["sid"]) && ($config["sid"] != ""))
35 {
36 $this->sid = $config["sid"];
37 }
38
39 if (isset($config["ttl_multiplier"]) && $this->useLock)
40 {
41 $this->ttlMultiplier = (integer)$config["ttl_multiplier"];
42 }
43 }
44
45 if (!empty($options) && isset($options['actual_data']))
46 {
47 $this->useLock = !((bool) $options['actual_data']);
48 }
49
50 $this->sid .= !$this->useLock;
51
52 if (!$this->useLock)
53 {
54 $this->ttlMultiplier = 1;
55 }
56 }
57
63 public function getReadBytes()
64 {
65 return $this->read;
66 }
67
73 public function getWrittenBytes()
74 {
75 return $this->written;
76 }
77
84 public function getCachePath()
85 {
86 return "";
87 }
88
94 public function isAvailable()
95 {
96 return function_exists('xcache_get');
97 }
98
110 protected function lock($baseDir, $initDir, $key, $TTL)
111 {
112 if (
113 isset(self::$locks[$baseDir])
114 && isset(self::$locks[$baseDir][$initDir])
115 && isset(self::$locks[$baseDir][$initDir][$key])
116 )
117 {
118 return true;
119 }
120 elseif (xcache_get($key)) //another process has the lock
121 {
122 return false;
123 }
124 else
125 {
126 $lock = xcache_inc($key, 1, intval($TTL));
127 if ($lock === 1) //we are lucky to be the first
128 {
129 self::$locks[$baseDir][$initDir][$key] = true;
130 return true;
131 }
132 //xcache_dec have to be never called due to concurrency with xcache_set($key."~", 1, intval($TTL));
133 }
134
135 return false;
136 }
137
148 protected function unlock($baseDir, $initDir = false, $key = false, $TTL = 0)
149 {
150 if ($key !== false)
151 {
152 if ($TTL > 0)
153 {
154 xcache_set($key, 1, intval($TTL));
155 }
156 else
157 {
158 xcache_unset($key);
159 }
160
161 unset(self::$locks[$baseDir][$initDir][$key]);
162 }
163 elseif ($initDir !== false)
164 {
165 if (isset(self::$locks[$baseDir][$initDir]))
166 {
167 foreach (self::$locks[$baseDir][$initDir] as $subKey)
168 {
169 $this->unlock($baseDir, $initDir, $subKey, $TTL);
170 }
171 unset(self::$locks[$baseDir][$initDir]);
172 }
173 }
174 elseif ($baseDir !== false)
175 {
176 if (isset(self::$locks[$baseDir]))
177 {
178 foreach (self::$locks[$baseDir] as $subInitDir)
179 {
180 $this->unlock($baseDir, $subInitDir, false, $TTL);
181 }
182 }
183 }
184 }
185
195 public function clean($baseDir, $initDir = false, $filename = false)
196 {
197 $key = false;
198 if($filename <> '')
199 {
200 $baseDirVersion = xcache_get($this->sid.$baseDir);
201 if($baseDirVersion === null)
202 {
203 return;
204 }
205
206 if($initDir !== false)
207 {
208 $initDirVersion = xcache_get($baseDirVersion."|".$initDir);
209 if($initDirVersion === null)
210 {
211 return;
212 }
213 }
214 else
215 {
216 $initDirVersion = "";
217 }
218
219 $key = $baseDirVersion."|".$initDirVersion."|".$filename;
220 xcache_unset($key);
221 }
222 else
223 {
224 if($initDir <> '')
225 {
226 $baseDirVersion = xcache_get($this->sid.$baseDir);
227 if($baseDirVersion === null)
228 {
229 return;
230 }
231
232 xcache_unset($baseDirVersion."|".$initDir);
233 }
234 else
235 {
236 xcache_unset($this->sid.$baseDir);
237 }
238 }
239 $this->unlock($baseDir, $initDir, $key."~");
240 }
241
253 public function read(&$allVars, $baseDir, $initDir, $filename, $TTL)
254 {
255 $baseDirVersion = xcache_get($this->sid.$baseDir);
256 if ($baseDirVersion === null)
257 return false;
258
259 if ($initDir !== false)
260 {
261 $initDirVersion = xcache_get($baseDirVersion."|".$initDir);
262 if ($initDirVersion === null)
263 return false;
264 }
265 else
266 {
267 $initDirVersion = "";
268 }
269
270 $key = $baseDirVersion."|".$initDirVersion."|".$filename;
271 $allVars = xcache_get($key);
272
273 if ($allVars === null)
274 {
275 return false;
276 }
277 else
278 {
279 if ($this->useLock)
280 {
281 if ($this->lock($baseDir, $initDir, $key."~", $TTL))
282 {
283 return false;
284 }
285 }
286
287 $this->read = mb_strlen($allVars);
288 $allVars = unserialize($allVars);
289 }
290
291 return true;
292 }
293
305 public function write($allVars, $baseDir, $initDir, $filename, $TTL)
306 {
307 $baseDirVersion = xcache_get($this->sid.$baseDir);
308 if ($baseDirVersion === null)
309 {
310 $baseDirVersion = md5(mt_rand());
311 if (!xcache_set($this->sid.$baseDir, $baseDirVersion))
312 return;
313 }
314
315 if ($initDir !== false)
316 {
317 $initDirVersion = xcache_get($baseDirVersion."|".$initDir);
318 if ($initDirVersion === null)
319 {
320 $initDirVersion = md5(mt_rand());
321 if (!xcache_set($baseDirVersion."|".$initDir, $initDirVersion))
322 return;
323 }
324 }
325 else
326 {
327 $initDirVersion = "";
328 }
329
330 $allVars = serialize($allVars);
331 $this->written = mb_strlen($allVars);
332
333 $key = $baseDirVersion."|".$initDirVersion."|".$filename;
334 xcache_set($key, $allVars, intval($TTL) * $this->ttlMultiplier);
335
336 if ($this->useLock)
337 {
338 $this->unlock($baseDir, $initDir, $key."~", $TTL);
339 }
340 }
341
350 public function isCacheExpired($path)
351 {
352 return false;
353 }
354}
write($allVars, $baseDir, $initDir, $filename, $TTL)
lock($baseDir, $initDir, $key, $TTL)
clean($baseDir, $initDir=false, $filename=false)
unlock($baseDir, $initDir=false, $key=false, $TTL=0)
read(&$allVars, $baseDir, $initDir, $filename, $TTL)