*/
public static function newEmpty() {
return new static( [
- 'cache' => new EmptyBagOStuff(),
- 'pool' => 'empty'
+ 'cache' => new EmptyBagOStuff()
] );
}
$purgeValues = [];
foreach ( $timeKeys as $timeKey ) {
$purge = isset( $wrappedValues[$timeKey] )
- ? self::parsePurgeValue( $wrappedValues[$timeKey] )
+ ? $this->parsePurgeValue( $wrappedValues[$timeKey] )
: false;
if ( $purge === false ) {
// Key is not set or invalid; regenerate
$newVal = $this->makePurgeValue( $now, self::HOLDOFF_TTL );
$this->cache->add( $timeKey, $newVal, self::CHECK_KEY_TTL );
- $purge = self::parsePurgeValue( $newVal );
+ $purge = $this->parsePurgeValue( $newVal );
}
$purgeValues[] = $purge;
}
$rawValues = $this->cache->getMulti( $rawKeys );
$rawValues += array_fill_keys( $rawKeys, false );
- $index = 0;
$times = [];
foreach ( $rawKeys as $key => $rawKey ) {
- $purge = self::parsePurgeValue( $rawValues[$rawKey] );
+ $purge = $this->parsePurgeValue( $rawValues[$rawKey] );
if ( $purge !== false ) {
$time = $purge[self::FLD_TIME];
} else {
* );
* @endcode
*
+ * Example usage (key holding an LRU subkey:value map; this can avoid flooding cache with
+ * keys for an unlimited set of (constraint,situation) pairs, thereby avoiding elevated
+ * cache evictions and wasted memory):
+ * @code
+ * $catSituationTolerabilityCache = $this->cache->getWithSetCallback(
+ * // Group by constraint ID/hash, cat family ID/hash, or something else useful
+ * $this->cache->makeKey( 'cat-situation-tolerablity-checks', $groupKey ),
+ * WANObjectCache::TTL_DAY, // rarely used groups should fade away
+ * // The $scenarioKey format is $constraintId:<ID/hash of $situation>
+ * function ( $cacheMap ) use ( $scenarioKey, $constraintId, $situation ) {
+ * $lruCache = MapCacheLRU::newFromArray( $cacheMap ?: [], self::CACHE_SIZE );
+ * $result = $lruCache->get( $scenarioKey ); // triggers LRU bump if present
+ * if ( $result === null || $this->isScenarioResultExpired( $result ) ) {
+ * $result = $this->checkScenarioTolerability( $constraintId, $situation );
+ * $lruCache->set( $scenarioKey, $result, 3 / 8 );
+ * }
+ * // Save the new LRU cache map and reset the map's TTL
+ * return $lruCache->toArray();
+ * },
+ * [
+ * // Once map is > 1 sec old, consider refreshing
+ * 'ageNew' => 1,
+ * // Update within 5 seconds after "ageNew" given a 1hz cache check rate
+ * 'hotTTR' => 5,
+ * // Avoid querying cache servers multiple times in a request; this also means
+ * // that a request can only alter the value of any given constraint key once
+ * 'pcTTL' => WANObjectCache::TTL_PROC_LONG
+ * ]
+ * );
+ * $tolerability = isset( $catSituationTolerabilityCache[$scenarioKey] )
+ * ? $catSituationTolerabilityCache[$scenarioKey]
+ * : $this->checkScenarioTolerability( $constraintId, $situation );
+ * @endcode
+ *
* @see WANObjectCache::get()
* @see WANObjectCache::set()
*
* @return bool Success
* @since 1.28
*/
- public function reap( $key, $purgeTimestamp, &$isStale = false ) {
+ final public function reap( $key, $purgeTimestamp, &$isStale = false ) {
$minAsOf = $purgeTimestamp + self::HOLDOFF_TTL;
$wrapped = $this->cache->get( self::VALUE_KEY_PREFIX . $key );
if ( is_array( $wrapped ) && $wrapped[self::FLD_TIME] < $minAsOf ) {
* @return bool Success
* @since 1.28
*/
- public function reapCheckKey( $key, $purgeTimestamp, &$isStale = false ) {
+ final public function reapCheckKey( $key, $purgeTimestamp, &$isStale = false ) {
$purge = $this->parsePurgeValue( $this->cache->get( self::TIME_KEY_PREFIX . $key ) );
if ( $purge && $purge[self::FLD_TIME] < $purgeTimestamp ) {
$isStale = true;
* @return ArrayIterator Iterator yielding (cache key => entity ID) in $entities order
* @since 1.28
*/
- public function makeMultiKeys( array $entities, callable $keyFunc ) {
+ final public function makeMultiKeys( array $entities, callable $keyFunc ) {
$map = [];
foreach ( $entities as $entity ) {
$map[$keyFunc( $entity, $this )] = $entity;
* @param bool $enabled Whether to enable interim caching
* @since 1.31
*/
- public function useInterimHoldOffCaching( $enabled ) {
+ final public function useInterimHoldOffCaching( $enabled ) {
$this->useInterimHoldOffCaching = $enabled;
}
* $ttl = ( $newList === $oldValue )
* // No change: cache for 150% of the age of $oldValue
* ? $cache->adaptiveTTL( $oldAsOf, $maxTTL, $minTTL, 1.5 )
- * // Changed: cache for %50 of the age of $oldValue
+ * // Changed: cache for 50% of the age of $oldValue
* : $cache->adaptiveTTL( $oldAsOf, $maxTTL, $minTTL, .5 );
* }
*
* @return int Number of warmup key cache misses last round
* @since 1.30
*/
- public function getWarmupKeyMisses() {
+ final public function getWarmupKeyMisses() {
return $this->warmupKeyMisses;
}
*/
protected function unwrap( $wrapped, $now ) {
// Check if the value is a tombstone
- $purge = self::parsePurgeValue( $wrapped );
+ $purge = $this->parsePurgeValue( $wrapped );
if ( $purge !== false ) {
// Purged values should always have a negative current $ttl
$curTTL = min( $purge[self::FLD_TIME] - $now, self::TINY_NEGATIVE );
* @return array|bool Array containing a UNIX timestamp (float) and holdoff period (integer),
* or false if value isn't a valid purge value
*/
- protected static function parsePurgeValue( $value ) {
+ protected function parsePurgeValue( $value ) {
if ( !is_string( $value ) ) {
return false;
}