@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class DivinerAtomCache extends DivinerDiskCache {
4
5 private $fileHashMap;
6 private $atomMap;
7 private $symbolMap;
8 private $edgeSrcMap;
9 private $edgeDstMap;
10 private $graphMap;
11
12 private $atoms = array();
13 private $writeAtoms = array();
14
15 public function __construct($cache_directory) {
16 parent::__construct($cache_directory, 'diviner-atom-cache');
17 }
18
19 public function delete() {
20 parent::delete();
21
22 $this->fileHashMap = null;
23 $this->atomMap = null;
24 $this->atoms = array();
25
26 return $this;
27 }
28
29/* -( File Hash Map )------------------------------------------------------ */
30
31
32 public function getFileHashMap() {
33 if ($this->fileHashMap === null) {
34 $this->fileHashMap = $this->getCache()->getKey('file', array());
35 }
36 return $this->fileHashMap;
37 }
38
39 public function addFileHash($file_hash, $atom_hash) {
40 $this->getFileHashMap();
41 $this->fileHashMap[$file_hash] = $atom_hash;
42 return $this;
43 }
44
45 public function fileHashExists($file_hash) {
46 $map = $this->getFileHashMap();
47 return isset($map[$file_hash]);
48 }
49
50 public function deleteFileHash($file_hash) {
51 if ($this->fileHashExists($file_hash)) {
52 $map = $this->getFileHashMap();
53 $atom_hash = $map[$file_hash];
54 unset($this->fileHashMap[$file_hash]);
55
56 $this->deleteAtomHash($atom_hash);
57 }
58
59 return $this;
60 }
61
62
63/* -( Atom Map )----------------------------------------------------------- */
64
65
66 public function getAtomMap() {
67 if ($this->atomMap === null) {
68 $this->atomMap = $this->getCache()->getKey('atom', array());
69 }
70 return $this->atomMap;
71 }
72
73 public function getAtom($atom_hash) {
74 if (!array_key_exists($atom_hash, $this->atoms)) {
75 $key = 'atom/'.$this->getHashKey($atom_hash);
76 $this->atoms[$atom_hash] = $this->getCache()->getKey($key);
77 }
78 return $this->atoms[$atom_hash];
79 }
80
81 public function addAtom(array $atom) {
82 $hash = $atom['hash'];
83 $this->atoms[$hash] = $atom;
84
85 $this->getAtomMap();
86 $this->atomMap[$hash] = true;
87
88 $this->writeAtoms['atom/'.$this->getHashKey($hash)] = $atom;
89
90 return $this;
91 }
92
93 public function deleteAtomHash($atom_hash) {
94 $atom = $this->getAtom($atom_hash);
95 if ($atom) {
96 foreach ($atom['childHashes'] as $child_hash) {
97 $this->deleteAtomHash($child_hash);
98 }
99 }
100
101 $this->getAtomMap();
102 unset($this->atomMap[$atom_hash]);
103 unset($this->writeAtoms[$atom_hash]);
104
105 $this->getCache()->deleteKey('atom/'.$this->getHashKey($atom_hash));
106
107 return $this;
108 }
109
110 public function saveAtoms() {
111 $this->getCache()->setKeys(
112 array(
113 'file' => $this->getFileHashMap(),
114 'atom' => $this->getAtomMap(),
115 ) + $this->writeAtoms);
116 $this->writeAtoms = array();
117 return $this;
118 }
119
120
121/* -( Symbol Hash Map )---------------------------------------------------- */
122
123
124 public function getSymbolMap() {
125 if ($this->symbolMap === null) {
126 $this->symbolMap = $this->getCache()->getKey('symbol', array());
127 }
128 return $this->symbolMap;
129 }
130
131 public function addSymbol($atom_hash, $symbol_hash) {
132 $this->getSymbolMap();
133 $this->symbolMap[$atom_hash] = $symbol_hash;
134 return $this;
135 }
136
137 public function deleteSymbol($atom_hash) {
138 $this->getSymbolMap();
139 unset($this->symbolMap[$atom_hash]);
140
141 return $this;
142 }
143
144 public function saveSymbols() {
145 $this->getCache()->setKeys(
146 array(
147 'symbol' => $this->getSymbolMap(),
148 ));
149 return $this;
150 }
151
152/* -( Edge Map )----------------------------------------------------------- */
153
154
155 public function getEdgeMap() {
156 if ($this->edgeDstMap === null) {
157 $this->edgeDstMap = $this->getCache()->getKey('edge', array());
158 $this->edgeSrcMap = array();
159 foreach ($this->edgeDstMap as $dst => $srcs) {
160 foreach ($srcs as $src => $ignored) {
161 $this->edgeSrcMap[$src][$dst] = true;
162 }
163 }
164 }
165 return $this->edgeDstMap;
166 }
167
168 public function getEdgesWithDestination($symbol_hash) {
169 $this->getEdgeMap();
170 return array_keys(idx($this->edgeDstMap, $symbol_hash, array()));
171 }
172
173 public function addEdges($node_hash, array $symbol_hash_list) {
174 $this->getEdgeMap();
175 $this->edgeSrcMap[$node_hash] = array_fill_keys($symbol_hash_list, true);
176 foreach ($symbol_hash_list as $symbol_hash) {
177 $this->edgeDstMap[$symbol_hash][$node_hash] = true;
178 }
179 return $this;
180 }
181
182 public function deleteEdges($node_hash) {
183 $this->getEdgeMap();
184 foreach (idx($this->edgeSrcMap, $node_hash, array()) as $dst => $ignored) {
185 unset($this->edgeDstMap[$dst][$node_hash]);
186 if (empty($this->edgeDstMap[$dst])) {
187 unset($this->edgeDstMap[$dst]);
188 }
189 }
190 unset($this->edgeSrcMap[$node_hash]);
191 return $this;
192 }
193
194 public function saveEdges() {
195 $this->getCache()->setKeys(
196 array(
197 'edge' => $this->getEdgeMap(),
198 ));
199 return $this;
200 }
201
202
203/* -( Graph Map )---------------------------------------------------------- */
204
205
206 public function getGraphMap() {
207 if ($this->graphMap === null) {
208 $this->graphMap = $this->getCache()->getKey('graph', array());
209 }
210 return $this->graphMap;
211 }
212
213 public function deleteGraph($node_hash) {
214 $this->getGraphMap();
215 unset($this->graphMap[$node_hash]);
216 return $this;
217 }
218
219 public function addGraph($node_hash, $graph_hash) {
220 $this->getGraphMap();
221 $this->graphMap[$node_hash] = $graph_hash;
222 return $this;
223 }
224
225 public function saveGraph() {
226 $this->getCache()->setKeys(
227 array(
228 'graph' => $this->getGraphMap(),
229 ));
230 return $this;
231 }
232
233}