Passed
Pull Request — 5.1 (#122)
by David
07:56 queued 03:20
created

NativeWeakrefObjectStorage   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 9
eloc 16
c 1
b 0
f 0
dl 0
loc 69
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A cleanupDanglingWeakRefs() 0 6 4
A remove() 0 3 1
A set() 0 7 2
A get() 0 6 2
1
<?php
2
declare(strict_types=1);
3
4
/*
5
 Copyright (C) 2006-2014 David Négrier - THE CODING MACHINE
6
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
*/
21
22
namespace TheCodingMachine\TDBM;
23
24
use WeakReference;
0 ignored issues
show
Bug introduced by
The type WeakReference was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
26
/**
27
 * The NativeWeakrefObjectStorage class is used to reference all beans that have been fetched from the database.
28
 * If a bean is requested twice from TDBM, the NativeWeakrefObjectStorage is used to "cache" the bean.
29
 * Unlike the StandardObjectStorage, the NativeWeakrefObjectStorage manages memory in a clever way, using WeakReference.
30
 * WeakReference have been added in PHP 7.4.
31
 *
32
 * @author David Negrier
33
 */
34
class NativeWeakrefObjectStorage implements ObjectStorageInterface
35
{
36
    /**
37
     * An array of fetched object, accessible via table name and primary key.
38
     * If the primary key is split on several columns, access is done by an array of columns, serialized.
39
     *
40
     * @var WeakReference[][]
41
     */
42
    private $objects = array();
43
44
    /**
45
     * Every 10000 set in the dataset, we perform a cleanup to ensure the WeakRef instances
46
     * are removed if they are no more valid.
47
     * This is to avoid having memory used by dangling WeakRef instances.
48
     *
49
     * @var int
50
     */
51
    private $garbageCollectorCount = 0;
52
53
    /**
54
     * Sets an object in the storage.
55
     *
56
     * @param string $tableName
57
     * @param string|int $id
58
     * @param DbRow  $dbRow
59
     */
60
    public function set(string $tableName, $id, DbRow $dbRow): void
61
    {
62
        $this->objects[$tableName][$id] = WeakReference::create($dbRow);
63
        ++$this->garbageCollectorCount;
64
        if ($this->garbageCollectorCount === 10000) {
65
            $this->garbageCollectorCount = 0;
66
            $this->cleanupDanglingWeakRefs();
67
        }
68
    }
69
70
    /**
71
     * Returns an object from the storage (or null if no object is set).
72
     *
73
     * @param string $tableName
74
     * @param string|int $id
75
     *
76
     * @return DbRow|null
77
     */
78
    public function get(string $tableName, $id) : ?DbRow
79
    {
80
        if (isset($this->objects[$tableName][$id])) {
81
            return $this->objects[$tableName][$id]->get();
82
        }
83
        return null;
84
    }
85
86
    /**
87
     * Removes an object from the storage.
88
     *
89
     * @param string $tableName
90
     * @param string|int $id
91
     */
92
    public function remove(string $tableName, $id): void
93
    {
94
        unset($this->objects[$tableName][$id]);
95
    }
96
97
    private function cleanupDanglingWeakRefs(): void
98
    {
99
        foreach ($this->objects as $tableName => $table) {
100
            foreach ($table as $id => $obj) {
101
                if ($obj->valid() === false) {
102
                    unset($this->objects[$tableName][$id]);
103
                }
104
            }
105
        }
106
    }
107
}
108