Skip to content

Core Interfaces Reference

This page provides a comprehensive reference for every core interface in the CoCache framework. Interfaces are organized by module and functional area.

Cache API Interfaces (cocache-api)

Cache<K, V>

The root cache interface that combines read and write operations.

AspectDetailSource
Packageme.ahoo.cache.api--
ExtendsCacheGetter<K, V>, CacheSetter<K, V>--
Type ParametersK -- cache key type, V -- cache value type--
Source File--Cache.kt:21
kotlin
interface Cache<K, V> : CacheGetter<K, V>, CacheSetter<K, V>

Cache<K, V> is a pure composition interface. All cache layers -- ClientSideCache, DistributedCache, CoherentCache, and JoinCache -- ultimately implement this interface.

CacheGetter<K, V>

Read-only cache access interface.

MethodSignatureDescriptionSource
getCachefun getCache(key: K): CacheValue<V>?Returns the full CacheValue wrapper (including TTL metadata) or null if absentCacheGetter.kt:21
getoperator fun get(key: K): V?Returns the unwrapped value or null. Strips TTL and missing-guard infoCacheGetter.kt:29
getTtlAtfun getTtlAt(key: K): Long?Returns the expiration timestamp (seconds) or null if key does not existCacheGetter.kt:37

CacheSetter<K, V>

Write and eviction interface.

MethodSignatureDescriptionSource
setoperator fun set(key: K, ttlAt: Long, value: V)Sets a value with an explicit expiration timestampCacheSetter.kt:18
setoperator fun set(key: K, value: V)Sets a value using the cache's default TTL configurationCacheSetter.kt:20
setCachefun setCache(key: K, value: CacheValue<V>)Sets a pre-constructed CacheValue (with TTL and missing-guard metadata)CacheSetter.kt:22
evictfun evict(key: K)Removes the entry from the cacheCacheSetter.kt:29

CacheValue<V>

Wraps a cached value with TTL and missing-guard metadata.

Property/MethodTypeDescriptionSource
valueVThe actual cached valueCacheValue.kt:21
ttlAtLongExpiration timestamp in seconds (ChronoUnit.SECONDS)CacheValue.kt:28
isMissingGuardBooleanWhether this value is a placeholder for a missing key (prevents cache penetration)CacheValue.kt:30

Extends TtlAt, inheriting isForever, isExpired, and expiredDuration.

Default Implementation: DefaultCacheValue -- companion object factory methods: forever(), ttlAt(), missingGuard().

TtlAt

Interface for time-to-live management based on absolute timestamps.

PropertyTypeDescriptionSource
ttlAtLongAbsolute expiration time in secondsTtlAt.kt:23
isForeverBooleanWhether this entry never expiresTtlAt.kt:29
isExpiredBooleanWhether the current time exceeds ttlAtTtlAt.kt:30
expiredDurationDurationRemaining time until expiration as a java.time.DurationTtlAt.kt:31

Default Implementation: ComputedTtlAt -- provides static utility methods at(ttl, amplitude) and isForever(ttl).

NamedCache

Identifies a cache by its logical name.

PropertyTypeDescriptionSource
cacheNameStringThe logical cache name, used for bean registration and event routingNamedCache.kt:21

ClientSideCache<V>

L2 client-side (in-process) cache interface.

AspectDetailSource
ExtendsCache<String, V>--
Key TypeString (converted via KeyConverter)--
Source File--ClientSideCache.kt:22
Property/MethodTypeDescription
sizeLongNumber of entries currently in the client-side cache
clearfun clear()Removes all entries from the local cache

Implementations:

ImplementationDescriptionModule
MapClientSideCacheConcurrentHashMap-backed, no eviction policycocache-core
GuavaClientSideCacheGuava Cache-backed with configurable size/time evictioncocache-core
CaffeineClientSideCacheCaffeine Cache-backed with configurable size/time evictioncocache-core

CacheSource<K, V>

L0 data source loader interface. Called when both L2 and L1 caches miss.

MethodSignatureDescriptionSource
loadCacheValuefun loadCacheValue(key: K): CacheValue<V>?Loads a value from the underlying data source. Returns null if the key does not exist. May throw TimeoutExceptionCacheSource.kt:24
Companion MethodDescription
noOp()Returns a singleton NoOpCacheSource that always returns null

Default Implementation: NoOpCacheSource -- object singleton, always returns null.

Core Module Interfaces (cocache-core)

DistributedCache<V>

L1 distributed (shared) cache interface.

AspectDetailSource
ExtendsComputedCache<String, V>, AutoCloseable--
Key TypeString--
Source File--DistributedCache.kt:22

Extends ComputedCache for default get(), set(), and getTtlAt() implementations, and AutoCloseable for resource cleanup.

Implementations:

ImplementationDescriptionModule
MockDistributedCacheIn-memory mock for testingcocache-core
RedisDistributedCacheRedis-backed distributed cache using StringRedisTemplatecocache-spring-redis

DistributedClientId

Identifies a cache client instance across the distributed system.

PropertyTypeDescriptionSource
clientIdStringUnique identifier for this cache client instance (used to avoid processing self-published events)DistributedClientId.kt:21

Default client ID generators: HostClientIdGenerator (uses host address), UUIDClientIdGenerator (random UUID).

ComputedCache<K, V>

Provides computed default implementations for Cache methods, bridging raw CacheValue access with user-friendly get/set operations.

AspectDetailSource
ExtendsCache<K, V>, TtlConfiguration--
Source File--ComputedCache.kt:20

Key behaviors:

  • get(key) -- calls getCache(key), returns null if missing guard or expired
  • getTtlAt(key) -- calls getCache(key), returns null if missing guard
  • set(key, value) -- creates DefaultCacheValue with default TTL + amplitude jitter
  • set(key, ttlAt, value) -- creates DefaultCacheValue with explicit TTL

CoherentCache<K, V>

The central interface for the Level 2 coherent cache, combining all cache concerns.

AspectDetailSource
ExtendsComputedCache<K, V>, DistributedClientId, NamedCache, CacheEvictedSubscriber--
Source File--CoherentCache.kt:25
PropertyTypeDescription
cacheEvictedEventBusCacheEvictedEventBusEvent bus for publishing/receiving eviction events
clientSideCacheClientSideCache<V>The L2 local cache
distributedCacheDistributedCache<V>The L1 distributed cache
keyFilterKeyFilterBloom filter for preventing cache penetration
keyConverterKeyConverter<K>Converts typed keys to string keys
cacheSourceCacheSource<K, V>The L0 data source

Default Implementation: DefaultCoherentCache -- implements fine-grained locking to prevent cache stampede, missing guard caching to prevent cache penetration, and event-driven coherence.

DefaultCoherentCache Fine-Grained Locking

The DefaultCoherentCache.getCache() method uses per-key locking to prevent cache stampede when multiple threads request the same missing key:

mermaid
flowchart TB
    subgraph Locking["Fine-Grained Lock Flow"]
        style Locking fill:#161b22,stroke:#6d5dfc,color:#e6edf3
        Start["getCache(key)"]
        L2Check["Check L2<br>(ClientSideCache)"]
        L2Hit{"L2 Hit?"}
        KFCheck["KeyFilter.notExist?"]
        KFMiss{"Key missing?"}
        L1Check["Check L1<br>(DistributedCache)"]
        L1Hit{"L1 Hit?"}
        Lock["Acquire per-key lock<br>synchronized(keyLock)"]
        L2Recheck["Re-check L2<br>(double-check)"]
        L2RHit{"L2 Hit now?"}
        L0Load["Load from L0<br>(CacheSource)"]
        L0Found{"Value found?"}
        SetBoth["Set L2 + L1<br>Publish event"]
        SetGuard["Set MissingGuard<br>in L2 + L1"]
        Return["Return value"]

        Start --> L2Check
        L2Check --> L2Hit
        L2Hit -- "yes" --> Return
        L2Hit -- "no" --> KFCheck
        KFCheck --> KFMiss
        KFMiss -- "yes" --> SetGuard
        KFMiss -- "no" --> L1Check
        L1Check --> L1Hit
        L1Hit -- "yes" --> SetBoth
        L1Hit -- "no" --> Lock
        Lock --> L2Recheck
        L2Recheck --> L2RHit
        L2RHit -- "yes" --> Return
        L2RHit -- "no" --> L0Load
        L0Load --> L0Found
        L0Found -- "yes" --> SetBoth
        L0Found -- "no" --> SetGuard
        SetBoth --> Return
        SetGuard --> Return
    end

CoherentCacheConfiguration<K, V>

Data class holding all configuration needed to create a CoherentCache.

PropertyTypeDefaultSource
cacheNameString(required)CoherentCacheConfiguration.kt:27
clientIdString(required)CoherentCacheConfiguration.kt:28
keyConverterKeyConverter<K>(required)CoherentCacheConfiguration.kt:29
distributedCacheDistributedCache<V>(required)CoherentCacheConfiguration.kt:30
clientSideCacheClientSideCache<V>MapClientSideCache()CoherentCacheConfiguration.kt:31
cacheSourceCacheSource<K, V>CacheSource.noOp()CoherentCacheConfiguration.kt:32
keyFilterKeyFilterNoOpKeyFilterCoherentCacheConfiguration.kt:33

Cache Coherence Interfaces

CacheEvictedEventBus

Publish-subscribe event bus for cache eviction events, ensuring distributed cache coherence.

MethodSignatureDescriptionSource
publishfun publish(event: CacheEvictedEvent)Publishes an eviction event to all subscribersCacheEvictedEventBus.kt:20
registerfun register(subscriber: CacheEvictedSubscriber)Registers a subscriber to receive eviction eventsCacheEvictedEventBus.kt:21
unregisterfun unregister(subscriber: CacheEvictedSubscriber)Removes a subscriber from receiving eventsCacheEvictedEventBus.kt:22

Implementations:

ImplementationScopeDescriptionModule
GuavaCacheEvictedEventBusSingle JVMUses Guava EventBus for in-process pub/subcocache-core
NoOpCacheEvictedEventBusNoneNo-op singleton, events are discardedcocache-core
RedisCacheEvictedEventBusDistributedUses Redis Pub/Sub for cross-instance event propagationcocache-spring-redis

CacheEvictedSubscriber

Interface for components that react to cache eviction events.

MethodSignatureDescriptionSource
onEvictedfun onEvicted(cacheEvictedEvent: CacheEvictedEvent)Called when a cache eviction event is receivedCacheEvictedSubscriber.kt:23

Extends NamedCache so subscribers know which cache they belong to.

CacheEvictedEvent

Data class representing a cache eviction event.

PropertyTypeDescriptionSource
cacheNameStringName of the cache from which the entry was evictedCacheEvictedEvent.kt:21
keyStringThe evicted cache key (string-converted)CacheEvictedEvent.kt:28
publisherIdStringClient ID of the instance that published the eventCacheEvictedEvent.kt:34

JoinCache Interfaces (cocache-api)

JoinCache<K1, V1, K2, V2>

Composes two cached values into a single JoinValue result.

AspectDetailSource
ExtendsCache<K1, JoinValue<V1, K2, V2>>--
Source File--JoinCache.kt:23
Property/MethodTypeDescription
joinKeyExtractorJoinKeyExtractor<V1, K2>Extracts the join key from the first value
evictfun evict(firstKey: K1, joinKey: K2)Evicts entries from both the first and join caches

JoinValue<V1, K2, V2>

Result type combining a primary value with a joined secondary value.

PropertyTypeDescriptionSource
firstValueV1The primary cached valueJoinValue.kt:16
joinKeyK2The key used to look up the secondary valueJoinValue.kt:17
secondValueV2?The joined secondary value (nullable if not found)JoinValue.kt:18

Default Implementation: DefaultJoinValue

JoinKeyExtractor<V1, K2>

Functional interface for extracting a join key from a primary value.

MethodSignatureDescriptionSource
extractfun extract(firstValue: V1): K2Extracts the join key from the first cache valueJoinKeyExtractor.kt:8

Implementations: ExpJoinKeyExtractor (SpEL expression-based, in cocache-core).

JoinCache Flow

The JoinCache retrieval flow works by fetching the primary value, extracting the join key, and then fetching the secondary value:

mermaid
sequenceDiagram
autonumber
    participant Caller as Caller
    participant JC as SimpleJoinCache
    participant FC as firstCache
    participant JKE as JoinKeyExtractor
    participant SC as secondCache (joinCache)

    Caller->>JC: getCache(firstKey)
    JC->>FC: getCache(firstKey)
    FC-->>JC: firstCacheValue
    JC->>JKE: extract(firstValue)
    JKE-->>JC: joinKey
    JC->>SC: getCache(joinKey)
    SC-->>JC: secondCacheValue
    JC-->>Caller: JoinValue(firstValue, joinKey, secondValue)

Key Filter Interfaces

KeyFilter

Cache key filter interface, designed to adapt Bloom filters for preventing cache breakdown.

MethodSignatureDescriptionSource
notExistfun notExist(key: String): BooleanReturns true if the key is definitely not in the data sourceKeyFilter.kt:22

Implementations:

ImplementationDescriptionModule
NoOpKeyFilterAlways returns false (no filtering)cocache-core
BloomKeyFilterUses Guava BloomFilter for probabilistic key existence checkingcocache-core

Client-Side Cache Implementations

mermaid
classDiagram
    direction LR

    class ClientSideCache~V~ {
        <<interface>>
        +size: Long
        +clear()
    }
    class Cache~String,V~ {
        <<interface>>
    }
    class MapClientSideCache~V~ {
        -cache: ConcurrentHashMap
        +getCache(key) CacheValue
        +setCache(key, value)
        +evict(key)
        +clear()
    }
    class GuavaClientSideCache~V~ {
        -cache: Guava~Cache~
        +getCache(key) CacheValue
        +setCache(key, value)
        +evict(key)
        +clear()
    }
    class CaffeineClientSideCache~V~ {
        -cache: Caffeine~Cache~
        +getCache(key) CacheValue
        +setCache(key, value)
        +evict(key)
        +clear()
    }

    Cache <|-- ClientSideCache
    ClientSideCache <|.. MapClientSideCache
    ClientSideCache <|.. GuavaClientSideCache
    ClientSideCache <|.. CaffeineClientSideCache

    style ClientSideCache fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style Cache fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style MapClientSideCache fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style GuavaClientSideCache fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CaffeineClientSideCache fill:#2d333b,stroke:#6d5dfc,color:#e6edf3

Key Converter Interfaces

KeyConverter<K>

Converts typed cache keys to string keys for storage.

MethodSignatureDescriptionSource
toStringKeyfun toStringKey(sourceKey: K): StringConverts a typed key to its string representation with prefixKeyConverter.kt:8

Implementations:

ImplementationDescriptionSource
ToStringKeyConverter<K>Simple keyPrefix + sourceKey.toString()ToStringKeyConverter.kt:20
ExpKeyConverter<K>SpEL expression-based key generation with prefixExpKeyConverter.kt:24

MissingGuard

Prevents cache penetration by caching null/missing values with a sentinel marker.

Constant/ExtensionDescriptionSource
STRING_VALUE = "_nil_"Sentinel string for missing values of type String, Set, or MapMissingGuard.kt:18
Any?.isMissingGuardExtension property checking if a value is a missing guardMissingGuard.kt:19

Factory Interfaces

All factory interfaces follow a common pattern: accept CoCacheMetadata (or JoinCacheMetadata) and produce the corresponding cache component.

Factory InterfaceProducesSource
CacheFactoryNamed Cache instances by name/typeCacheFactory.kt:19
CoherentCacheFactoryCoherentCache from CoherentCacheConfigurationCoherentCacheFactory.kt:16
CacheProxyFactoryProxy-based Cache implementationsCacheProxyFactory.kt:19
ClientSideCacheFactoryClientSideCache<V> instancesClientSideCacheFactory.kt:19
DistributedCacheFactoryDistributedCache<V> instancesDistributedCacheFactory.kt:18
CacheSourceFactoryCacheSource<K, V> instancesCacheSourceFactory.kt:19
KeyConverterFactoryKeyConverter<K> instancesKeyConverterFactory.kt:18
JoinKeyExtractorFactoryJoinKeyExtractor<V1, K2> instancesJoinKeyExtractorFactory.kt:19
JoinCacheProxyFactoryProxy-based JoinCache implementationsJoinCacheProxyFactory.kt:19

Interface Relationship Diagram

The following diagram shows how the factory interfaces compose to produce a working cache:

mermaid
graph TB
    subgraph Inputs["Inputs"]
        style Inputs fill:#161b22,stroke:#6d5dfc,color:#e6edf3
        Meta["CoCacheMetadata<br>(parsed from @CoCache)"]
    end

    subgraph Factories["Factory Layer"]
        style Factories fill:#161b22,stroke:#6d5dfc,color:#e6edf3
        KCF["KeyConverterFactory"]
        CSF["ClientSideCacheFactory"]
        DCF["DistributedCacheFactory"]
        CSrcF["CacheSourceFactory"]
        CCGF["CoherentCacheFactory"]
        CPF["CacheProxyFactory"]
    end

    subgraph Products["Produced Components"]
        style Products fill:#161b22,stroke:#6d5dfc,color:#e6edf3
        KC["KeyConverter"]
        CSC["ClientSideCache"]
        DC["DistributedCache"]
        CSrc["CacheSource"]
        CC["CoherentCache"]
        Proxy["Cache Proxy"]
    end

    Meta --> KCF
    Meta --> CSF
    Meta --> DCF
    Meta --> CSrcF
    KCF --> KC
    CSF --> CSC
    DCF --> DC
    CSrcF --> CSrc
    KC --> CCGF
    CSC --> CCGF
    DC --> CCGF
    CSrc --> CCGF
    CCGF --> CC
    CC --> CPF
    Meta --> CPF
    CPF --> Proxy

Released under the Apache License 2.0.