CacheCompressed.php 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. <?php
  2. /**
  3. * This typically brings 80..85% compression in ~20ms/mb write, 5ms/mb read.
  4. */
  5. class Redis_CacheCompressed extends Redis_Cache implements DrupalCacheInterface
  6. {
  7. private $compressionSizeThreshold = 100;
  8. private $compressionRatio = 1;
  9. /**
  10. * {@inheritdoc}
  11. */
  12. public function __construct($bin)
  13. {
  14. parent::__construct($bin);
  15. $this->compressionSizeThreshold = (int)variable_get('cache_compression_size_threshold', 100);
  16. if ($this->compressionSizeThreshold < 0) {
  17. trigger_error('cache_compression_size_threshold must be 0 or a positive integer, negative value found, switching back to default 100', E_USER_WARNING);
  18. $this->compressionSizeThreshold = 100;
  19. }
  20. // Minimum compression level (1) has good ratio in low time.
  21. $this->compressionRatio = (int)variable_get('cache_compression_ratio', 1);
  22. if ($this->compressionRatio < 1 || 9 < $this->compressionRatio) {
  23. trigger_error('cache_compression_ratio must be between 1 and 9, out of bounds value found, switching back to default 1', E_USER_WARNING);
  24. $this->compressionRatio = 1;
  25. }
  26. }
  27. /**
  28. * {@inheritdoc}
  29. */
  30. protected function createEntryHash($cid, $data, $expire = CACHE_PERMANENT)
  31. {
  32. $hash = parent::createEntryHash($cid, $data, $expire);
  33. // Empiric level when compression makes sense.
  34. if (!$this->compressionSizeThreshold || strlen($hash['data']) > $this->compressionSizeThreshold) {
  35. $hash['data'] = gzcompress($hash['data'], $this->compressionRatio);
  36. $hash['compressed'] = true;
  37. }
  38. return $hash;
  39. }
  40. /**
  41. * {@inheritdoc}
  42. */
  43. protected function expandEntry(array $values, $flushPerm, $flushVolatile)
  44. {
  45. if (!empty($values['data']) && !empty($values['compressed'])) {
  46. // Uncompress, suppress warnings e.g. for broken CRC32.
  47. $values['data'] = @gzuncompress($values['data']);
  48. // In such cases, void the cache entry.
  49. if ($values['data'] === false) {
  50. return false;
  51. }
  52. }
  53. return parent::expandEntry($values, $flushPerm, $flushVolatile);
  54. }
  55. }