Passed
Pull Request — 5.3 (#283)
by
unknown
09:13
created

NativeWeakrefObjectStorage::remove()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 Copyright (C) 2006-2014 David Négrier - THE CODING MACHINE
7
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
12
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21
*/
22
23
namespace TheCodingMachine\TDBM;
24
25
use WeakReference;
26
27
/**
28
 * The NativeWeakrefObjectStorage class is used to reference all beans that have been fetched from the database.
29
 * If a bean is requested twice from TDBM, the NativeWeakrefObjectStorage is used to "cache" the bean.
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
    /**
98
     * Removes all objects from the storage.
99
     */
100
    public function clear(): void
101
    {
102
        $this->objects = array();
103
    }
104
105
    private function cleanupDanglingWeakRefs(): void
106
    {
107
        foreach ($this->objects as $tableName => $table) {
108
            foreach ($table as $id => $obj) {
109
                if ($obj->get() === null) {
110
                    unset($this->objects[$tableName][$id]);
111
                }
112
            }
113
        }
114
    }
115
}
116