summaryrefslogtreecommitdiff
path: root/classes/cache
diff options
context:
space:
mode:
Diffstat (limited to 'classes/cache')
-rw-r--r--classes/cache/Cache_interface.php34
-rw-r--r--classes/cache/FileCache.php93
-rw-r--r--classes/cache/MemcachedCache.php37
-rw-r--r--classes/cache/RedisCache.php69
4 files changed, 233 insertions, 0 deletions
diff --git a/classes/cache/Cache_interface.php b/classes/cache/Cache_interface.php
new file mode 100644
index 0000000..7c49789
--- /dev/null
+++ b/classes/cache/Cache_interface.php
@@ -0,0 +1,34 @@
+<?php
+
+/** Cache interface
+ * ---
+ * Interface to save results of expensive data-extraction proccess,
+ * in a fast-accessed medium (ussually RAM or NVME SSD units)
+ */
+interface Cache_interface
+{
+ /** Cache::set($key, $data, $ttl) : void
+ *
+ * @param $key (string): reference label
+ * @param $data (mixed): actual data (avoid storing true|false)
+ * @param $ttl (int): time to live (seconds)
+ */
+ public function set(string $key, $data, int $ttl);
+
+
+ /** Cache::get($key) : mixed
+ *
+ * @param $key (string)
+ * @return mixed: fetched $data -or- false on failure
+ */
+ public function get(string $key);
+
+
+ /** Cache::flush( $olderThan ) : void
+ *
+ * clear cache older than $olderThan
+ * @param $olderThan (int) in seconds
+ */
+ public function flush(int $olderThan = 0);
+
+} \ No newline at end of file
diff --git a/classes/cache/FileCache.php b/classes/cache/FileCache.php
new file mode 100644
index 0000000..fb7eee5
--- /dev/null
+++ b/classes/cache/FileCache.php
@@ -0,0 +1,93 @@
+<?php
+
+/* FileCache
+ * ---
+ * Saves serialized data into filesystem.
+ * Use it for expensive database-queries.
+ * Performanve on a NVMe-SSD drive is really great;
+ * (even better than MemCached and Redis)
+ * performance on a typical HDD is just fair.
+ *
+ * NOTE:
+ * Memcached and Redis are much faster cache-technologies
+ * and generally recommended; but they are not always available;
+ * FileCache is (almost) always available;
+ *
+ * Before tou decide on your caching technology
+ * run some benchmarks.
+ */
+class FileCache implements Cache_interface
+{
+
+ /** store
+ * ---
+ * serializes and saves data in a file
+ * along with TTL (time-to-live)
+ */
+ public function set(string $key, $data, int $ttl)
+ {
+ // filename is a hashed 48-hex-digit string
+ // probability of collision = exp( (-k*(k-1)) / 2N )
+ // ex: for 10tril.samples P(collision) = 1.5E-11%
+ $filename = FILECACHE_PATH . sha1($key);
+
+ // Opening file for write
+ $h = fopen($filename, 'w');
+ if (!$h) throw new Exception('Can not write to cache');
+
+ // Serialize along with the TTL
+ $data = serialize( array(
+ time() + $ttl, // array[0] holds expiration time
+ $data) // array[1] holds the actual data
+ );
+
+ if (fwrite($h,$data) === false) {
+ throw new Exception('Can not write to cache');
+ }
+ fclose($h);
+ }
+
+
+ /** fetch
+ * ---
+ * feth data for certain key
+ * @param $key (string)
+ * @return fetched $data -or- false on failure
+ */
+ public function get(string $key)
+ {
+ $filename = FILECACHE_PATH . sha1($key);
+
+ // can not read the cache-file? return false
+ if (!file_exists($filename) || !is_readable($filename)) return false;
+
+ $data = file_get_contents($filename); // get cache-file contents
+ $data = @unserialize($data); // unserialize
+
+ if (!$data) {
+
+ // Unlinking the file when unserializing failed
+ unlink($filename);
+ return false;
+
+ }
+
+ // checking if the data was expired
+ if (time() > $data[0]) {
+
+ // Unlinking
+ unlink($filename);
+ return false;
+
+ }
+
+ return $data[1];
+ }
+
+
+ public function flush(int $olderThan = 0)
+ {
+ return false; // reply false until implementation
+ }
+
+}
diff --git a/classes/cache/MemcachedCache.php b/classes/cache/MemcachedCache.php
new file mode 100644
index 0000000..c89d86a
--- /dev/null
+++ b/classes/cache/MemcachedCache.php
@@ -0,0 +1,37 @@
+<?php
+
+/** Memcached Implementation
+ * (implements Cache interface; extends Cache)
+ * ---
+ */
+class MemcachedCache implements Cache_interface
+{
+
+ public function set($key, $data, $ttl)
+ {
+ $hashkey = md5($key);
+
+ $mc = new Memcached();
+ $mc->addServer(\MEMCACHE_HOST, 11211);
+
+ $mc->set($hashkey, $data, $ttl);
+ }
+
+
+ public function get($key)
+ {
+ $hashkey = md5($key);
+
+ $mc = new Memcached();
+ $mc->addServer(\MEMCACHE_HOST, 11211);
+
+ return $mc->get($hashkey);
+
+ }
+
+ public function flush($olderThan = 0)
+ {
+ return false;
+ }
+
+} \ No newline at end of file
diff --git a/classes/cache/RedisCache.php b/classes/cache/RedisCache.php
new file mode 100644
index 0000000..ec50f08
--- /dev/null
+++ b/classes/cache/RedisCache.php
@@ -0,0 +1,69 @@
+<?php
+
+/** Redis Cache implementation
+ * ---
+ * This class uses \Predis\Redis, so do not forget require it via composer
+ * or to use the configuration options you will find into \README.md
+ */
+class RedisCache implements Cache_interface
+{
+ /** set
+ * store $data under the label $key
+ * cache expires in $ttl seconds
+ */
+ public function set($key, $data, $ttl)
+ {
+ $serialized = serialize($data);
+
+ if ($serialized = '') {
+ return false;
+ }
+
+ try {
+ $redis = new \Predis\Client([
+ 'host' => \REDIS_HOST
+ ]);
+ return $redis->set($key, $serialized, 'EX', $ttl);
+
+ } catch (Exception $e) {
+ // ...
+ }
+ }
+
+
+ /** get
+ * fetch previously stored $data under label $key
+ * return $data (or false)
+ */
+ public function get($key)
+ {
+
+ try {
+
+ $redis = new \Predis\Client([
+ 'host' => \REDIS_HOST
+ ]);
+
+ if ($redis->exists($key)) {
+ return unserialize($redis->get($key));
+
+ } else {
+ return false;
+ }
+
+ } catch (Exception $e) {
+ // ...
+ }
+
+ }
+
+
+ /** flush
+ * --- not umplemented yet; may not needed
+ */
+ public function flush($olderThan = 0)
+ {
+ return false; // until implementation
+ }
+
+} \ No newline at end of file