Campustream 1.0
A social network MQP for WPI
|
00001 <?php 00002 00003 class ActiveCache { 00004 00005 private $run_sql = false; 00006 private $find_all = false; 00007 private $result_set = null; 00008 private $object = null; 00009 private static $mem_cache = array(); 00010 00011 public static function find( $class, $cache_key, $expire=0 ) { 00012 00013 $memcache = MemcacheManager::connection(); 00014 00015 $table_name = ActiveRecord::model_to_table_name( $class ); 00016 $cache_key = substr($table_name, 0, -1) . '/' . $cache_key; 00017 00018 Logger::debug( "looking up cache key $cache_key"); 00019 00020 if (!empty(self::$mem_cache[$cache_key])) { 00021 Logger::debug( "using local cache key $cache_key" ); 00022 return new ActiveCache( $class, $cache_key, $expire, self::$mem_cache[$cache_key]); 00023 } elseif ( ( $result = $memcache->get( $cache_key ) ) !== false ) { 00024 return new ActiveCache( $class, $cache_key, $expire, $result ); 00025 } else { 00026 return new ActiveCache( $class, $cache_key, $expire ); 00027 } 00028 00029 } 00030 00031 public static function find_all( $class, $cache_key, $expire=0 ) { 00032 00033 $memcache = MemcacheManager::connection(); 00034 00035 $table_name = ActiveRecord::model_to_table_name( $class ); 00036 $cache_key = $table_name . '/' . $cache_key; 00037 00038 Logger::debug( "looking up cache key $cache_key"); 00039 00040 00041 if (!empty(self::$mem_cache[$cache_key])) { 00042 Logger::debug( "using local cache key $cache_key" ); 00043 return new ActiveCache( $class, $cache_key, $expire, self::$mem_cache[$cache_key]); 00044 } elseif ( ( $result = $memcache->get( $cache_key ) ) !== false ) { 00045 return new ActiveCache( $class, $cache_key, $expire, $result, true ); 00046 Logger::debug( "found cache key $cache_key"); 00047 } else { 00048 return new ActiveCache( $class, $cache_key, $expire, null, true ); 00049 } 00050 00051 } 00052 00053 public static function invalidate_keys_for( ActiveRecord $object ) { 00054 $memcache = MemcacheManager::connection(); 00055 00056 foreach ( $object->cache_keys as $cache_key => $replace ) { 00057 if ( $replace !== null ) $cache_key = str_replace( '#', $object->{$replace}, $cache_key ); 00058 $memcache->delete( $cache_key ); 00059 Logger::debug( "deleting $cache_key" ); 00060 } 00061 } 00062 00063 public function __construct( $class, $cache_key, $expire=0, $result=null, $find_all=false ) { 00064 $this->class = $class; 00065 $this->cache_key = $cache_key; 00066 00067 if ( $expire == 0 ) { 00068 $this->expire = 0; 00069 } else { 00070 $this->expire = $expire + time(); 00071 } 00072 // used to keep track if being called w/ find_all or find 00073 $this->find_all = $find_all; 00074 if ( $result === null ) { 00075 $this->run_sql = true; 00076 return; 00077 } 00078 00079 $this->result_set = $result; 00080 00081 } 00082 00083 public function sql( $clause ) { 00084 // only run the sql if nothing was found in the cache 00085 if ( $this->run_sql === true ) { 00086 00087 $memcache = MemcacheManager::connection(); 00088 00089 if ( $this->find_all === false ) { 00090 $this->result_set = ActiveRecord::find( $this->class, $clause ); 00091 if ( $this->result_set->is_loaded() === false ) return $this->result_set; // we don't want to cache an empty object 00092 } else { 00093 $this->result_set = ActiveRecord::find_all( $this->class, $clause ); 00094 } 00095 00096 Logger::debug( "setting cache key $this->cache_key"); 00097 $memcache->set( $this->cache_key, $this->result_set, $this->expire); 00098 00099 } 00100 00101 self::$mem_cache[$this->cache_key] = $this->result_set; 00102 00103 // subscribe to save() and delete() events, which will call 00104 // ActiveCache->notify and invalidate cache keys automatically. 00105 00106 if ( is_array( $this->result_set ) ) { 00107 foreach( $this->result_set as $result ) { 00108 $result->cache_keys[ $this->cache_key ] = null; 00109 $result->subscribe( $this ); 00110 } 00111 } else { 00112 $this->result_set->cache_keys[ $this->cache_key ] = null; 00113 $this->result_set->subscribe( $this ); 00114 } 00115 00116 $result_set = $this->result_set; 00117 $this->result_set = null; 00118 00119 00120 return $result_set; 00121 00122 } 00123 00124 public function notify( ActiveRecord $object ) { 00125 ActiveCache::invalidate_keys_for( $object ); 00126 } 00127 }