]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/InProcessCache/InProcessCachePlugin.php
1b6fbcdbea372f70e7521333349d350ddbe5c17b
[quix0rs-gnu-social.git] / plugins / InProcessCache / InProcessCachePlugin.php
1 <?php
2 /**
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2010, StatusNet, Inc.
5  *
6  * Extra level of caching, in memory
7  *
8  * PHP version 5
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Affero General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Affero General Public License for more details.
19  *
20  * You should have received a copy of the GNU Affero General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  * @category  Cache
24  * @package   StatusNet
25  * @author    Evan Prodromou <evan@status.net>
26  * @copyright 2010 StatusNet, Inc.
27  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
28  * @link      http://status.net/
29  */
30
31 if (!defined('STATUSNET')) {
32     // This check helps protect against security problems;
33     // your code file can't be executed directly from the web.
34     exit(1);
35 }
36
37 /**
38  * Extra level of caching
39  *
40  * This plugin adds an extra level of in-process caching to any regular
41  * cache system like APC, XCache, or Memcache.
42  * 
43  * Note that since most caching plugins return false for StartCache*
44  * methods, you should add this plugin before them, i.e.
45  *
46  *     addPlugin('InProcessCache');
47  *     addPlugin('XCache');
48  *
49  * @category  Cache
50  * @package   StatusNet
51  * @author    Evan Prodromou <evan@status.net>
52  * @copyright 2010 StatusNet, Inc.
53  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
54  * @link      http://status.net/
55  */
56
57 class InProcessCachePlugin extends Plugin
58 {
59     private $_items = array();
60     private $_hits  = array();
61
62     /**
63      * Get an item from the cache
64      * 
65      * Called before other cache systems are called (iif this
66      * plugin was loaded correctly, see class comment). If we
67      * have the data, return it, and don't hit the other cache
68      * systems.
69      *
70      * @param string &$key   Key to fetch
71      * @param mixed  &$value Resulting value or false for miss
72      *
73      * @return boolean false if found, else true
74      */
75
76     function onStartCacheGet(&$key, &$value)
77     {
78         if (array_key_exists($key, $this->_items)) {
79             $value = $this->_items[$key];
80             if (array_key_exists($key, $this->_hits)) {
81                 $this->_hits[$key]++;
82             } else {
83                 $this->_hits[$key] = 1;
84             }
85             Event::handle('EndCacheGet', array($key, &$value));
86             return false;
87         }
88         return true;
89     }
90
91     /**
92      * Called at the end of a cache get
93      *
94      * If we don't already have the data, we cache it. This
95      * keeps us from having to call the external cache if the
96      * key is requested again.
97      *
98      * @param string $key    Key to fetch
99      * @param mixed  &$value Resulting value or false for miss
100      *
101      * @return boolean hook value, true
102      */
103
104     function onEndCacheGet($key, &$value)
105     {
106         if (!array_key_exists($key, $this->_items) || 
107             $this->_items[$key] != $value) {
108             $this->_items[$key] = $value;
109         }
110         return true;
111     }
112
113     /**
114      * Called at the end of setting a cache element
115      * 
116      * Always set the cache element; may overwrite existing
117      * data.
118      *
119      * @param string  $key    Key to fetch
120      * @param mixed   $value  Resulting value or false for miss
121      * @param integer $flag   ignored
122      * @param integer $expiry ignored
123      *
124      * @return boolean true
125      */
126
127     function onEndCacheSet($key, $value, $flag, $expiry)
128     {
129         $this->_items[$key] = $value;
130         return true;
131     }
132
133     /**
134      * Called at the end of deleting a cache element
135      *
136      * If stuff's deleted from the other cache, we
137      * delete it too.
138      *
139      * @param string  &$key     Key to delete
140      * @param boolean &$success Success flag; ignored
141      *
142      * @return boolean true
143      */
144      
145     function onStartCacheDelete(&$key, &$success)
146     {
147         if (array_key_exists($key, $this->_items)) {
148             unset($this->_items[$key]);
149         }
150         return true;
151     }
152
153     /**
154      * Version info
155      *
156      * @param array &$versions Array of version blocks
157      *
158      * @return boolean true
159      */
160
161     function onPluginVersion(&$versions)
162     {
163         $url = 'http://status.net/wiki/Plugin:InProcessCache';
164
165         $versions[] = array('name' => 'InProcessCache',
166                             'version' => STATUSNET_VERSION,
167                             'author' => 'Evan Prodromou',
168                             'homepage' => $url,
169                             'description' =>
170                             _m('Additional in-process cache for plugins.'));
171         return true;
172     }
173
174     /**
175      * Cleanup function; called at end of process
176      *
177      * If the inprocess/stats config value is true, we dump
178      * stats to the log file
179      *
180      * @return boolean true
181      */
182
183     function cleanup()
184     {
185         if (common_config('inprocess', 'stats')) {
186             $this->log(LOG_INFO, "cache size: " . 
187                        count($this->_items));
188             $sum = 0;
189             foreach ($this->_hits as $hitcount) {
190                 $sum += $hitcount;
191             }
192             $this->log(LOG_INFO, $sum . " hits on " . 
193                        count($this->_hits) . " keys");
194         }
195         return true;
196     }
197 }