Completed
Push — work-fleets ( 046d2e...0cb966 )
by SuperNova.WS
07:26
created

SnCache::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
rs 10
c 1
b 0
f 0
ccs 0
cts 2
cp 0
crap 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
   * @var db_mysql $db
43
   */
44
  protected $db;
45
46
  /**
47
   * SnDbCachedOperator constructor.
48
   *
49
   * @param \Common\GlobalContainer $gc
50
   */
51
  public function __construct($gc) {
52
    $this->db = $gc->db;
0 ignored issues
show
Documentation Bug introduced by
It seems like $gc->db can also be of type object<Closure>. However, the property $db is declared as type object<db_mysql>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
53
  }
54
55
56
  /**
57
   * Repacking data for $location_type
58
   *
59
   * @param int $location_type
60
   * @param int $record_id
61
   */
62
  public function cache_repack($location_type, $record_id = 0) {
63
    // Если есть $user_id - проверяем, а надо ли перепаковывать?
64
    if ($record_id && isset(static::$data[$location_type][$record_id]) && static::$data[$location_type][$record_id] !== null) {
65
      return;
66
    }
67
68
    HelperArray::array_repack(static::$data[$location_type]);
69
    HelperArray::array_repack(static::$locator[$location_type], 3); // TODO У каждого типа локации - своя глубина!!!! Но можно и глубже ???
70
    HelperArray::array_repack(static::$queries[$location_type], 1);
71
  }
72
73
  public function cache_clear($location_type, $hard = true) {
74
    if ($hard && !empty(static::$data[$location_type])) {
75
      // Здесь нельзя делать unset - надо записывать NULL, что бы это отразилось на зависимых записях
76
      // TODO - replace with setNull
77
      array_walk(static::$data[$location_type], 'setNull');
78
    }
79
    static::$locator[$location_type] = array();
80
    static::$queries[$location_type] = array();
81
    $this->cache_repack($location_type); // Перепаковываем внутренние структуры, если нужно
82
  }
83
84
  // 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...
85
  public function cache_clear_all($hard = true) {
86
    if ($hard) {
87
      static::$data = array();
88
      static::cache_lock_unset_all();
89
    }
90
    static::$locator = array();
91
    static::$queries = array();
92
  }
93
94
  public function cache_isset($location_type, $record_id) {
95
    return isset(static::$data[$location_type][$record_id]) && static::$data[$location_type][$record_id] !== null;
96
  }
97
98
  // 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...
99
  public function cache_get($location_type, $record_id) {
100
    return isset(static::$data[$location_type][$record_id]) ? static::$data[$location_type][$record_id] : null;
101
  }
102
103
  /* Кэшируем запись в соответствующий кэш
104
105
  Писать в кэш:
106
  1. Если записи не существует в кэше
107
  2. Если стоит $force_overwrite
108
  3. Если во время транзакции существующая запись не заблокирована
109
110
  Блокировать запись:
111
  1. Если идет транзакция и запись не заблокирована
112
  2. Если не стоит скип-лок
113
  */
114
  public function cache_set($location_type, $record, $force_overwrite = false, $skip_lock = false) {
115
    // нет идентификатора - выход
116
    if (!($record_id = $record[SnDbCachedOperator::$location_info[$location_type][P_ID]])) {
117
      return;
118
    }
119
120
    $in_transaction = $this->db->getTransaction()->check(false);
121
    if (
122
      $force_overwrite
123
      ||
124
      // Не заменяются заблокированные записи во время транзакции
125
      ($in_transaction && !$this->cache_lock_get($location_type, $record_id))
126
      ||
127
      !$this->cache_isset($location_type, $record_id)
128
    ) {
129
      static::$data[$location_type][$record_id] = $record;
130
      if ($in_transaction && !$skip_lock) {
131
        $this->cache_lock_set($location_type, $record_id);
132
      }
133
    }
134
  }
135
136
  public function queryCacheSetByFilter($location_type, $filter, $record_id) {
137
    self::$queries[$location_type][$filter][$record_id] = &$this->getDataRefByLocationAndId($location_type, $record_id);
138
  }
139
140
  public function cache_unset($cache_id, $safe_record_id) {
141
    // $record_id должен быть проверен заранее !
142
    if (isset(static::$data[$cache_id][$safe_record_id]) && static::$data[$cache_id][$safe_record_id] !== null) {
143
      // Выставляем запись в null
144
      static::$data[$cache_id][$safe_record_id] = null;
145
      // Очищаем кэш мягко - что бы удалить очистить связанные данные - кэш локаций и кэш запоросов и всё, что потребуется впредь
146
      $this->cache_clear($cache_id, false);
147
    }
148
  }
149
150
  public function cache_lock_get($location_type, $record_id) {
151
    return isset(static::$locks[$location_type][$record_id]);
152
  }
153
154
  public function cache_lock_set($location_type, $record_id) {
155
    return static::$locks[$location_type][$record_id] = true; // Не всегда - от результата
156
  }
157
158
  // 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...
159
  public function cache_lock_unset($location_type, $record_id) {
160
    if (isset(static::$locks[$location_type][$record_id])) {
161
      unset(static::$locks[$location_type][$record_id]);
162
    }
163
164
    return true; // Не всегда - от результата
165
  }
166
167
  public function cache_lock_unset_all() {
168
    // Когда будем работать с xcache - это понадобиться, что бы снимать в xcache блокировки с записей
169
    // Пройти по массиву - снять блокировки для кэшера в памяти
170
    static::$locks = array();
171
172
    return true; // Не всегда - от результата
173
  }
174
175
  public function getData($locationType = LOC_NONE) {
176
    return $locationType == LOC_NONE ? static::$data : static::$data[$locationType];
177
  }
178
179
  public function cacheUnsetElement($locationType, $recordId) {
180
    static::$data[$locationType][$recordId] = null;
181
  }
182
183
  public function isArrayLocation($locationType) {
184
    return is_array(static::$data[$locationType]);
185
  }
186
187
  /**
188
   * Return reference to record in $data by locationType and recordId
189
   *
190
   * @param int $locationType
191
   * @param int $recordId
192
   *
193
   * @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...
194
   */
195
  public function &getDataRefByLocationAndId($locationType, $recordId) {
196
    return static::$data[$locationType][$recordId];
197
  }
198
199
  // TODO UNUSED ????
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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...
200
  public function setUnitLocator($unit, $unit_id) {
201
    if (is_array($unit)) {
202
      static::$locator[LOC_UNIT][$unit['unit_location_type']][$unit['unit_location_id']][$unit['unit_snid']] = &$this->getDataRefByLocationAndId(LOC_UNIT, $unit_id);
203
    }
204
  }
205
206
  public function getUnitLocator($location_type, $location_id, $unit_snid) {
207
    return $unit_snid ? static::$locator[LOC_UNIT][$location_type][$location_id][$unit_snid] : static::$locator[LOC_UNIT][$location_type][$location_id];
208
  }
209
210
  public function getUnitLocatorByFullLocation($location_type, $location_id) {
211
    return is_array(static::$locator[LOC_UNIT][$location_type][$location_id]) ? static::$locator[LOC_UNIT][$location_type][$location_id] : array();
212
  }
213
214
  public function setUnitLocatorByLocationAndIDs($location_type, $location_id, $unit_data) {
215
    self::$locator[LOC_UNIT][$location_type][$location_id][$unit_data['unit_snid']] = &static::$data[LOC_UNIT][$unit_data['unit_id']];
216
  }
217
218
  public function isUnitLocatorNotSet($location_type, $location_id) {
219
    return !isset(static::$locator[LOC_UNIT][$location_type][$location_id]);
220
  }
221
222
  public function locatorReset() {
223
    static::$locator = array();
224
  }
225
226
  public function queriesReset() {
227
    static::$queries = array();
228
  }
229
230
  public function getQueries() {
231
    return static::$queries;
232
  }
233
234
  public function getLocks() {
235
    return static::$locks;
236
  }
237
238
  public function getQueriesByLocationAndFilter($locationType, $filter) {
239
    return !empty(static::$queries[$locationType][$filter]) && is_array(static::$queries[$locationType][$filter]) ? static::$queries[$locationType][$filter] : array();
240
  }
241
242
  public function isQueryCacheByLocationAndFilterEmpty($locationType, $filter) {
243
    return !isset(self::$queries[$locationType][$filter]) || self::$queries[$locationType][$filter] === null;
244
  }
245
246
  public function queryCacheResetByLocationAndFilter($locationType, $filter) {
247
    self::$queries[$locationType][$filter] = array();
248
  }
249
250
}
251