Completed
Push — work-fleets ( 60e3d3...5fa106 )
by SuperNova.WS
06:18
created

SnCache::cache_repack()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 6
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 10
rs 9.2
1
<?php
2
3
/**
4
 * Class SnCache
5
 *
6
 * Permanent cache for classSupernova
7
 */
8
class SnCache {
9
  /**
10
   * Кэш данных - юзера, планеты, юниты, очередь, альянсы итд
11
   *
12
   * @var array $data
13
   */
14
  protected static $data = array();
15
16
  /**
17
   * Кэширует соответствия между расположением объектов - в частности юнитов и очередей
18
   *
19
   * Массив $locator - хранит отношения между записями для быстрого доступа по тип_записи:тип_локации:ид_локации:внутренний_ид_записи=>информация
20
   * Для LOC_UNIT внутренний ИД - это SNID, а информация - это ссылка на запись `unit`
21
   * Для LOC_QUE внутренний ИД - это тип очереди, а информация - массив ссылок на `que`
22
   *
23
   * @var array $locator
24
   */
25
  protected static $locator = array();
26
27
  /**
28
   * Кэш запросов
29
   *
30
   * @var array $queries
31
   */
32
  protected static $queries = array();
33
34
  /**
35
   * Информация о блокировках
36
   *
37
   * @var array $locks
38
   */
39
  protected static $locks = array();
40
41
  /**
42
   * Repacking data for $location_type
43
   *
44
   * @param int $location_type
45
   * @param int $record_id
46
   */
47
  public static function cache_repack($location_type, $record_id = 0) {
48
    // Если есть $user_id - проверяем, а надо ли перепаковывать?
49
    if ($record_id && isset(static::$data[$location_type][$record_id]) && static::$data[$location_type][$record_id] !== null) {
50
      return;
51
    }
52
53
    HelperArray::array_repack(static::$data[$location_type]);
54
    HelperArray::array_repack(static::$locator[$location_type], 3); // TODO У каждого типа локации - своя глубина!!!! Но можно и глубже ???
55
    HelperArray::array_repack(static::$queries[$location_type], 1);
56
  }
57
58
  public static function cache_clear($location_type, $hard = true) {
59
    if ($hard && !empty(static::$data[$location_type])) {
60
      // Здесь нельзя делать unset - надо записывать NULL, что бы это отразилось на зависимых записях
61
      // TODO - replace with setNull
62
      array_walk(static::$data[$location_type], function (&$item) { $item = null; });
63
    }
64
    static::$locator[$location_type] = array();
65
    static::$queries[$location_type] = array();
66
    static::cache_repack($location_type); // Перепаковываем внутренние структуры, если нужно
67
  }
68
69
  public static function setNull(&$item) {
70
    $item = null;
71
  }
72
73
  public static function cache_clear_all($hard = true) {
74
    if ($hard) {
75
      static::$data = array();
76
      static::cache_lock_unset_all();
77
    }
78
    static::$locator = array();
79
    static::$queries = array();
80
  }
81
82
  public static function cache_isset($location_type, $record_id) {
83
    return isset(static::$data[$location_type][$record_id]) && static::$data[$location_type][$record_id] !== null;
84
  }
85
86
  // TODO - UNUSED ????????????
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
87
  public static function cache_get($location_type, $record_id) {
88
    return isset(static::$data[$location_type][$record_id]) ? static::$data[$location_type][$record_id] : null;
89
  }
90
91
  /* Кэшируем запись в соответствующий кэш
92
93
  Писать в кэш:
94
  1. Если записи не существует в кэше
95
  2. Если стоит $force_overwrite
96
  3. Если во время транзакции существующая запись не заблокирована
97
98
  Блокировать запись:
99
  1. Если идет транзакция и запись не заблокирована
100
  2. Если не стоит скип-лок
101
  */
102
  public static function cache_set($location_type, $record, $force_overwrite = false, $skip_lock = false) {
103
    // нет идентификатора - выход
104
    if (!($record_id = $record[classSupernova::$location_info[$location_type][P_ID]])) {
105
      return;
106
    }
107
108
    $in_transaction = classSupernova::db_transaction_check(false);
109
    if (
110
      $force_overwrite
111
      ||
112
      // Не заменяются заблокированные записи во время транзакции
113
      ($in_transaction && !static::cache_lock_get($location_type, $record_id))
114
      ||
115
      !static::cache_isset($location_type, $record_id)
116
    ) {
117
      static::$data[$location_type][$record_id] = $record;
118
      if ($in_transaction && !$skip_lock) {
119
        static::cache_lock_set($location_type, $record_id);
120
      }
121
    }
122
  }
123
124
  public static function queryCacheSetByFilter($location_type, $filter, $record_id) {
125
    SnCache::$queries[$location_type][$filter][$record_id] = &SnCache::getDataRefByLocationAndId($location_type, $record_id);
126
  }
127
128
  public static function cache_unset($cache_id, $safe_record_id) {
129
    // $record_id должен быть проверен заранее !
130
    if (isset(static::$data[$cache_id][$safe_record_id]) && static::$data[$cache_id][$safe_record_id] !== null) {
131
      // Выставляем запись в null
132
      static::$data[$cache_id][$safe_record_id] = null;
133
      // Очищаем кэш мягко - что бы удалить очистить связанные данные - кэш локаций и кэш запоросов и всё, что потребуется впредь
134
      static::cache_clear($cache_id, false);
135
    }
136
  }
137
138
  public static function cache_lock_get($location_type, $record_id) {
139
    return isset(static::$locks[$location_type][$record_id]);
140
  }
141
142
  public static function cache_lock_set($location_type, $record_id) {
143
    return static::$locks[$location_type][$record_id] = true; // Не всегда - от результата
144
  }
145
146
  // TODO - UNUSED ????????????
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
147
  public static function cache_lock_unset($location_type, $record_id) {
148
    if (isset(static::$locks[$location_type][$record_id])) {
149
      unset(static::$locks[$location_type][$record_id]);
150
    }
151
152
    return true; // Не всегда - от результата
153
  }
154
155
  public static function cache_lock_unset_all() {
156
    // Когда будем работать с xcache - это понадобиться, что бы снимать в xcache блокировки с записей
157
    // Пройти по массиву - снять блокировки для кэшера в памяти
158
    static::$locks = array();
159
160
    return true; // Не всегда - от результата
161
  }
162
163
  public static function getData($locationType = LOC_NONE) {
164
    return $locationType == LOC_NONE ? static::$data : static::$data[$locationType];
165
  }
166
167
  public static function cacheUnsetElement($locationType, $recordId) {
168
    static::$data[$locationType][$recordId] = null;
169
  }
170
171
  public static function isArrayLocation($locationType) {
172
    return is_array(static::$data[$locationType]);
173
  }
174
175
  /**
176
   * Return reference to record in $data by locationType and recordId
177
   *
178
   * @param int $locationType
179
   * @param int $recordId
180
   *
181
   * @return &mixed
0 ignored issues
show
Documentation introduced by
The doc-type &mixed could not be parsed: Unknown type name "&mixed" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
182
   */
183
  public static function &getDataRefByLocationAndId($locationType, $recordId) {
184
    return static::$data[$locationType][$recordId];
185
  }
186
187
  public static function setUnitLocator($unit, $unit_id) {
188
    if (is_array($unit)) {
189
      static::$locator[LOC_UNIT][$unit['unit_location_type']][$unit['unit_location_id']][$unit['unit_snid']] = &static::getDataRefByLocationAndId(LOC_UNIT, $unit_id);
190
    }
191
  }
192
193
  public static function getUnitLocator($location_type, $location_id, $unit_snid) {
194
    return $unit_snid ? static::$locator[LOC_UNIT][$location_type][$location_id][$unit_snid] : static::$locator[LOC_UNIT][$location_type][$location_id];
195
  }
196
197
  public static function getUnitLocatorByFullLocation($location_type, $location_id) {
198
    return is_array(static::$locator[LOC_UNIT][$location_type][$location_id]) ? static::$locator[LOC_UNIT][$location_type][$location_id] : array();
199
  }
200
201
  public static function setUnitLocatorByLocationAndIDs($location_type, $location_id, $unit_data) {
202
    SnCache::$locator[LOC_UNIT][$location_type][$location_id][$unit_data['unit_snid']] = &static::$data[LOC_UNIT][$unit_data['unit_id']];
203
  }
204
205
  public static function isUnitLocatorNotSet($location_type, $location_id) {
206
    return !isset(static::$locator[LOC_UNIT][$location_type][$location_id]);
207
  }
208
209
  public static function locatorReset() {
210
    static::$locator = array();
211
  }
212
213
  public static function queriesReset() {
214
    static::$queries = array();
215
  }
216
217
  public static function getQueries() {
218
    return static::$queries;
219
  }
220
221
  public static function getLocks() {
222
    return static::$locks;
223
  }
224
225
  public static function getQueriesByLocationAndFilter($locationType, $filter) {
226
    return !empty(static::$queries[$locationType][$filter]) && is_array(static::$queries[$locationType][$filter]) ? static::$queries[$locationType][$filter] : array();
227
  }
228
229
  public static function isQueryCacheByLocationAndFilterEmpty($locationType, $filter) {
230
    return !isset(SnCache::$queries[$locationType][$filter]) || SnCache::$queries[$locationType][$filter] === null;
231
  }
232
233
  public static function queryCacheResetByLocationAndFilter($locationType, $filter) {
234
    SnCache::$queries[$locationType][$filter] = array();
235
  }
236
}
237