# capacity-fixed

`software.visionary.cache:capacity-fixed:2026.10.13` · https://codeberg.org/caching/capacity-fixed

Fixed-size cache capacity: bound a cache by how many keys it keeps

<code>FixedSize</code> is a <code>Capacity</code> exceeded when it has counted more distinct keys than its limit.

## Rationale

**Why.** The number of keys is a bound a caller can state before knowing anything about the values.

## Key Concepts

### Counting keys

**Role.** Each <code>Insert</code> counts its key and each <code>Evict</code> releases it, so each cache needs its own instance. Holding exactly the limit is not exceeded.

**Pattern.** STRATEGY, OBSERVER

## How It Works

**Guarantees.** No public parameter takes null and no public method returns it, declared with contrax's <code>@PreCondition(IsNotNull.class)</code> and <code>@PostCondition(IsNotNull.class)</code>. A limit below one throws <code>IllegalArgumentException</code>. Keys are distinct by <code>equals</code>.

**Thread safety.** <code>update</code> and <code>exceeded()</code> may be called concurrently.

## Lane

**Purpose.** Bounding a cache by how many keys it keeps.

**Alternative.** <code>capacity-heap</code> to bound a cache by the JVM's used heap.

**When to avoid.** Values whose sizes differ widely: a count of keys says nothing of the memory they hold.

## Usage

A limit of two: a repeated key counts once, and a Hit changes nothing

```java
import java.time.Instant;
import software.visionary.cache.capacity.Capacity;
import software.visionary.cache.capacity.fixed.FixedSize;
import software.visionary.cache.events.Evict;
import software.visionary.cache.events.Hit;
import software.visionary.cache.events.Insert;

Instant now = Instant.now();
Capacity<String> capacity = new FixedSize<>(2);

capacity.update(new Insert.Key<>("a", now));
capacity.update(new Insert.Key<>("a", now));
capacity.update(new Insert.Key<>("b", now));
System.out.println(capacity.exceeded());

capacity.update(new Insert.Key<>("c", now));
capacity.update(new Hit.Occurred<>("c", now));
System.out.println(capacity.exceeded());

capacity.update(new Evict.Occurred<>("a", now));
System.out.println(capacity.exceeded());

```

Output

```text
false
true
false
```

## Dependencies

- `software.visionary:cache:2026.10.13` at Compile
- `software.visionary.contrax:processor:2026.10.13` at Processor
- `software.visionary:junit-closure:2026.09.17` at Testing

