or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Caffeine Guava

1

2

Caffeine Guava provides a compatibility adapter that enables seamless migration from Guava caches to Caffeine's high-performance caching library. The adapter wraps Caffeine cache instances in familiar Guava Cache API interfaces, allowing applications to benefit from Caffeine's superior performance characteristics (TinyLFU admission policy, advanced eviction strategies, and optimized concurrent access) while maintaining full API compatibility with existing Guava cache code.

3

4

## Package Information

5

6

- **Package Name**: guava

7

- **Package Type**: maven

8

- **Language**: Java

9

- **Installation**: `implementation 'com.github.ben-manes.caffeine:guava:3.2.0'`

10

- **Maven Coordinate**: `com.github.ben-manes.caffeine:guava`

11

12

## Core Imports

13

14

```java

15

import com.github.benmanes.caffeine.guava.CaffeinatedGuava;

16

import com.github.benmanes.caffeine.cache.Caffeine;

17

import com.google.common.cache.Cache;

18

import com.google.common.cache.LoadingCache;

19

import com.google.common.cache.CacheLoader;

20

21

// For static factory methods

22

import java.util.function.Function;

23

import java.util.concurrent.Executor;

24

```

25

26

## Basic Usage

27

28

```java

29

import com.github.benmanes.caffeine.guava.CaffeinatedGuava;

30

import com.github.benmanes.caffeine.cache.Caffeine;

31

import com.google.common.cache.Cache;

32

import com.google.common.cache.LoadingCache;

33

import com.google.common.cache.CacheLoader;

34

import java.time.Duration;

35

36

// Create a simple Guava-compatible cache from Caffeine

37

Cache<String, String> cache = CaffeinatedGuava.build(

38

Caffeine.newBuilder()

39

.maximumSize(1000)

40

.expireAfterWrite(Duration.ofMinutes(10))

41

);

42

43

cache.put("key", "value");

44

String value = cache.getIfPresent("key");

45

46

// Create a loading cache with Guava CacheLoader

47

LoadingCache<String, String> loadingCache = CaffeinatedGuava.build(

48

Caffeine.newBuilder()

49

.maximumSize(1000)

50

.expireAfterAccess(Duration.ofMinutes(5)),

51

new CacheLoader<String, String>() {

52

@Override

53

public String load(String key) throws Exception {

54

return loadFromDatabase(key);

55

}

56

}

57

);

58

59

String loadedValue = loadingCache.get("key");

60

```

61

62

## Architecture

63

64

The Caffeine Guava adapter is built around several key components:

65

66

- **CaffeinatedGuava**: Main utility class providing static factory methods for creating Guava-compatible cache instances

67

- **CaffeinatedGuavaCache**: Adapter that implements Guava's `Cache` interface while delegating to a Caffeine cache instance

68

- **CaffeinatedGuavaLoadingCache**: Specialized adapter extending `CaffeinatedGuavaCache` that implements Guava's `LoadingCache` interface

69

- **Cache Loader Adapters**: Internal classes that bridge between Guava and Caffeine loader interfaces, handling both single-key and bulk loading scenarios

70

- **Exception Translation**: Automatic conversion between Caffeine and Guava exception types to maintain API compatibility

71

72

## Capabilities

73

74

### Cache Creation

75

76

Creates Guava Cache facades around Caffeine cache instances.

77

78

```java { .api }

79

/**

80

* Returns a Caffeine cache wrapped in a Guava Cache facade.

81

* @param builder the configured cache builder

82

* @param <K> the most general key type to create caches for

83

* @param <V> the most general value type to create caches for

84

* @param <K1> the key type of the cache

85

* @param <V1> the value type of the cache

86

* @return a cache exposed under the Guava APIs

87

*/

88

public static <K, V, K1 extends K, V1 extends V> Cache<K1, V1> build(Caffeine<K, V> builder);

89

```

90

91

**Usage Example:**

92

93

```java

94

import com.github.benmanes.caffeine.cache.Caffeine;

95

import com.github.benmanes.caffeine.guava.CaffeinatedGuava;

96

import com.google.common.cache.Cache;

97

import java.time.Duration;

98

99

Cache<String, Integer> cache = CaffeinatedGuava.build(

100

Caffeine.newBuilder()

101

.maximumSize(10000)

102

.expireAfterWrite(Duration.ofHours(1))

103

.recordStats()

104

);

105

106

// Use as a normal Guava Cache

107

cache.put("count", 42);

108

Integer count = cache.getIfPresent("count");

109

cache.invalidate("count");

110

```

111

112

### Loading Cache Creation with Guava Loader

113

114

Creates Guava LoadingCache facades around Caffeine cache instances using Guava CacheLoader.

115

116

```java { .api }

117

/**

118

* Returns a Caffeine cache wrapped in a Guava LoadingCache facade.

119

* @param builder the configured cache builder

120

* @param loader the cache loader used to obtain new values

121

* @param <K> the most general key type to create caches for

122

* @param <V> the most general value type to create caches for

123

* @param <K1> the key type of the cache

124

* @param <V1> the value type of the cache

125

* @return a cache exposed under the Guava APIs

126

*/

127

public static <K, V, K1 extends K, V1 extends V> LoadingCache<K1, V1> build(

128

Caffeine<K, V> builder,

129

CacheLoader<? super K1, V1> loader

130

);

131

```

132

133

**Usage Example:**

134

135

```java

136

import com.google.common.cache.CacheLoader;

137

import com.google.common.cache.LoadingCache;

138

import java.util.concurrent.ExecutionException;

139

import java.util.Map;

140

import java.util.Arrays;

141

142

LoadingCache<String, String> userCache = CaffeinatedGuava.build(

143

Caffeine.newBuilder()

144

.maximumSize(1000)

145

.expireAfterAccess(Duration.ofMinutes(30)),

146

new CacheLoader<String, String>() {

147

@Override

148

public String load(String userId) throws Exception {

149

return fetchUserFromDatabase(userId);

150

}

151

152

@Override

153

public Map<String, String> loadAll(Iterable<? extends String> keys) throws Exception {

154

return fetchUsersFromDatabase(keys);

155

}

156

}

157

);

158

159

try {

160

String user = userCache.get("user123");

161

Map<String, String> users = userCache.getAll(Arrays.asList("user1", "user2"));

162

} catch (ExecutionException e) {

163

// Handle loading exceptions

164

}

165

```

166

167

### Loading Cache Creation with Caffeine Loader

168

169

Creates Guava LoadingCache facades around Caffeine cache instances using Caffeine CacheLoader.

170

171

```java { .api }

172

/**

173

* Returns a Caffeine cache wrapped in a Guava LoadingCache facade.

174

* @param builder the configured cache builder

175

* @param loader the cache loader used to obtain new values

176

* @param <K> the most general key type to create caches for

177

* @param <V> the most general value type to create caches for

178

* @param <K1> the key type of the cache

179

* @param <V1> the value type of the cache

180

* @return a cache exposed under the Guava APIs

181

*/

182

public static <K, V, K1 extends K, V1 extends V> LoadingCache<K1, V1> build(

183

Caffeine<K, V> builder,

184

com.github.benmanes.caffeine.cache.CacheLoader<? super K1, V1> loader

185

);

186

```

187

188

**Usage Example:**

189

190

```java

191

import com.github.benmanes.caffeine.cache.CacheLoader;

192

import java.util.concurrent.CompletableFuture;

193

import java.util.concurrent.Executor;

194

195

LoadingCache<String, String> configCache = CaffeinatedGuava.build(

196

Caffeine.newBuilder()

197

.refreshAfterWrite(Duration.ofMinutes(5))

198

.maximumSize(500),

199

new com.github.benmanes.caffeine.cache.CacheLoader<String, String>() {

200

@Override

201

public String load(String key) throws Exception {

202

return loadConfigValue(key);

203

}

204

205

@Override

206

public CompletableFuture<String> asyncReload(String key, String oldValue, Executor executor) {

207

return CompletableFuture.supplyAsync(() -> {

208

try {

209

return loadConfigValue(key);

210

} catch (Exception e) {

211

throw new RuntimeException(e);

212

}

213

}, executor);

214

}

215

}

216

);

217

```

218

219

### Cache Loader Adaptation

220

221

Converts Guava CacheLoader to Caffeine CacheLoader for direct use with Caffeine APIs.

222

223

```java { .api }

224

/**

225

* Returns a Caffeine cache loader that delegates to a Guava cache loader.

226

* @param loader the cache loader used to obtain new values

227

* @param <K> the type of keys

228

* @param <V> the type of values

229

* @return a cache loader exposed under the Caffeine APIs

230

*/

231

public static <K, V> com.github.benmanes.caffeine.cache.CacheLoader<K, V> caffeinate(

232

CacheLoader<K, V> loader

233

);

234

```

235

236

**Usage Example:**

237

238

```java

239

// Existing Guava CacheLoader

240

CacheLoader<String, String> guavaLoader = new CacheLoader<String, String>() {

241

@Override

242

public String load(String key) throws Exception {

243

return expensiveOperation(key);

244

}

245

};

246

247

// Convert to Caffeine CacheLoader

248

com.github.benmanes.caffeine.cache.CacheLoader<String, String> caffeineLoader =

249

CaffeinatedGuava.caffeinate(guavaLoader);

250

251

// Use with native Caffeine cache

252

com.github.benmanes.caffeine.cache.LoadingCache<String, String> nativeCache =

253

Caffeine.newBuilder()

254

.maximumSize(1000)

255

.build(caffeineLoader);

256

```

257

258

### CacheLoader Factory Methods

259

260

Creates CacheLoader instances using static factory methods for common patterns.

261

262

#### from() Method

263

264

Creates a CacheLoader from a Function for simple loading scenarios.

265

266

```java { .api }

267

/**

268

* Returns a cache loader that uses the provided function for loading values.

269

* @param function the function to use for loading values

270

* @param <K> the type of keys

271

* @param <V> the type of values

272

* @return a cache loader that delegates to the function

273

*/

274

public static <K, V> CacheLoader<K, V> from(Function<K, V> function);

275

```

276

277

**Usage Example:**

278

279

```java

280

import com.google.common.cache.CacheLoader;

281

import java.util.function.Function;

282

283

// Create a simple loader using a lambda

284

CacheLoader<String, String> loader = CacheLoader.from(key -> "value-for-" + key);

285

286

// Use with cache creation

287

LoadingCache<String, String> cache = CaffeinatedGuava.build(

288

Caffeine.newBuilder().maximumSize(1000),

289

loader

290

);

291

292

String value = cache.get("mykey"); // Returns "value-for-mykey"

293

```

294

295

#### asyncReloading() Method

296

297

Wraps an existing CacheLoader to perform asynchronous reloads in the background.

298

299

```java { .api }

300

/**

301

* Returns a cache loader that performs asynchronous reloads.

302

* @param loader the cache loader to wrap

303

* @param executor the executor to use for async operations

304

* @param <K> the type of keys

305

* @param <V> the type of values

306

* @return a cache loader that performs async reloads

307

*/

308

public static <K, V> CacheLoader<K, V> asyncReloading(

309

CacheLoader<K, V> loader,

310

Executor executor

311

);

312

```

313

314

**Usage Example:**

315

316

```java

317

import com.google.common.cache.CacheLoader;

318

import java.util.concurrent.Executors;

319

import java.util.concurrent.Executor;

320

321

// Original synchronous loader

322

CacheLoader<String, String> syncLoader = new CacheLoader<String, String>() {

323

@Override

324

public String load(String key) throws Exception {

325

return fetchFromDatabase(key); // Slow operation

326

}

327

};

328

329

// Wrap for asynchronous reloading

330

Executor executor = Executors.newFixedThreadPool(5);

331

CacheLoader<String, String> asyncLoader = CacheLoader.asyncReloading(syncLoader, executor);

332

333

// Use with refresh-enabled cache

334

LoadingCache<String, String> cache = CaffeinatedGuava.build(

335

Caffeine.newBuilder()

336

.maximumSize(1000)

337

.refreshAfterWrite(Duration.ofMinutes(5)), // Triggers async reload

338

asyncLoader

339

);

340

```

341

342

## Types

343

344

### Cache Interface

345

346

The adapter implements the complete Guava Cache interface:

347

348

```java { .api }

349

public interface Cache<K, V> {

350

V getIfPresent(Object key);

351

V get(K key, Callable<? extends V> valueLoader) throws ExecutionException;

352

ImmutableMap<K, V> getAllPresent(Iterable<?> keys);

353

void put(K key, V value);

354

void putAll(Map<? extends K, ? extends V> m);

355

void invalidate(Object key);

356

void invalidateAll(Iterable<?> keys);

357

void invalidateAll();

358

long size();

359

CacheStats stats();

360

ConcurrentMap<K, V> asMap();

361

void cleanUp();

362

}

363

```

364

365

### LoadingCache Interface

366

367

The adapter implements the complete Guava LoadingCache interface:

368

369

```java { .api }

370

public interface LoadingCache<K, V> extends Cache<K, V>, Function<K, V> {

371

V get(K key) throws ExecutionException;

372

V getUnchecked(K key);

373

ImmutableMap<K, V> getAll(Iterable<? extends K> keys) throws ExecutionException;

374

V apply(K key); // Deprecated

375

void refresh(K key);

376

}

377

```

378

379

### CacheLoader Class

380

381

Standard Guava CacheLoader that can be used with the adapter:

382

383

```java { .api }

384

public abstract class CacheLoader<K, V> {

385

public abstract V load(K key) throws Exception;

386

public Map<K, V> loadAll(Iterable<? extends K> keys) throws Exception;

387

public ListenableFuture<V> reload(K key, V oldValue) throws Exception;

388

389

// Static factory methods

390

public static <K, V> CacheLoader<K, V> from(Function<K, V> function);

391

public static <K, V> CacheLoader<K, V> asyncReloading(

392

CacheLoader<K, V> loader, Executor executor);

393

}

394

```

395

396

### Exception Types

397

398

The adapter handles and translates various exception types:

399

400

```java { .api }

401

// Thrown when a cache loader returns null

402

public class InvalidCacheLoadException extends RuntimeException;

403

404

// Wrapper for checked exceptions during cache loading

405

public class ExecutionException extends Exception;

406

407

// Wrapper for runtime exceptions during cache loading

408

public class UncheckedExecutionException extends RuntimeException;

409

410

// Wrapper for errors during cache loading

411

public class ExecutionError extends Error;

412

```

413

414

## Error Handling

415

416

The Caffeine Guava adapter provides comprehensive exception translation between Caffeine and Guava APIs:

417

418

- **Null Values**: `InvalidCacheLoadException` is thrown when cache loaders return null values

419

- **Checked Exceptions**: Wrapped in `ExecutionException` for methods that declare it

420

- **Runtime Exceptions**: Wrapped in `UncheckedExecutionException` for unchecked methods

421

- **Errors**: Wrapped in `ExecutionError` to maintain proper error propagation

422

- **Interrupted Operations**: Properly handle thread interruption during cache loading

423

424

**Example Error Handling:**

425

426

```java

427

import java.util.concurrent.ExecutionException;

428

import com.google.common.cache.CacheLoader.InvalidCacheLoadException;

429

430

try {

431

String value = loadingCache.get("key");

432

} catch (ExecutionException e) {

433

Throwable cause = e.getCause();

434

if (cause instanceof MyCustomException) {

435

// Handle specific exception

436

}

437

} catch (InvalidCacheLoadException e) {

438

// Handle null value from loader

439

}

440

```