Skip to content

Commit 0feed77

Browse files
Backport to branch(3) : Disable negative cache for table metadata (#3190)
Co-authored-by: Toshihiro Suzuki <[email protected]>
1 parent a47d2e7 commit 0feed77

File tree

6 files changed

+255
-53
lines changed

6 files changed

+255
-53
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ subprojects {
4444
googleCloudStorageVersion = '2.60.0'
4545
picocliVersion = '4.7.7'
4646
commonsTextVersion = '1.14.0'
47+
caffeineVersion = '2.9.3'
4748
junitVersion = '5.14.1'
4849
commonsLangVersion = '3.20.0'
4950
assertjVersion = '3.27.6'

core/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ dependencies {
197197
exclude group: 'org.slf4j', module: 'slf4j-api'
198198
}
199199
implementation "org.apache.commons:commons-text:${commonsTextVersion}"
200+
implementation "com.github.ben-manes.caffeine:caffeine:${caffeineVersion}"
200201
testImplementation platform("org.junit:junit-bom:${junitVersion}")
201202
testImplementation 'org.junit.jupiter:junit-jupiter'
202203
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

core/src/main/java/com/scalar/db/common/TableMetadataManager.java

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,37 @@
11
package com.scalar.db.common;
22

3-
import com.google.common.cache.CacheBuilder;
4-
import com.google.common.cache.CacheLoader;
5-
import com.google.common.cache.LoadingCache;
3+
import com.github.benmanes.caffeine.cache.Caffeine;
4+
import com.github.benmanes.caffeine.cache.LoadingCache;
65
import com.scalar.db.api.Admin;
76
import com.scalar.db.api.Operation;
87
import com.scalar.db.api.TableMetadata;
98
import com.scalar.db.exception.storage.ExecutionException;
109
import com.scalar.db.util.ScalarDbUtils;
1110
import com.scalar.db.util.ThrowableFunction;
1211
import java.util.Objects;
13-
import java.util.Optional;
12+
import java.util.concurrent.CompletionException;
1413
import java.util.concurrent.TimeUnit;
15-
import javax.annotation.Nonnull;
14+
import javax.annotation.Nullable;
1615
import javax.annotation.concurrent.ThreadSafe;
1716

1817
/** A class that manages and caches table metadata */
1918
@ThreadSafe
2019
public class TableMetadataManager {
2120

22-
private final LoadingCache<TableKey, Optional<TableMetadata>> tableMetadataCache;
21+
private final LoadingCache<TableKey, TableMetadata> tableMetadataCache;
2322

2423
public TableMetadataManager(Admin admin, long cacheExpirationTimeSecs) {
25-
this(
26-
key -> Optional.ofNullable(admin.getTableMetadata(key.namespace, key.table)),
27-
cacheExpirationTimeSecs);
24+
this(key -> admin.getTableMetadata(key.namespace, key.table), cacheExpirationTimeSecs);
2825
}
2926

3027
public TableMetadataManager(
31-
ThrowableFunction<TableKey, Optional<TableMetadata>, Exception> getTableMetadataFunc,
28+
ThrowableFunction<TableKey, TableMetadata, Exception> getTableMetadataFunc,
3229
long cacheExpirationTimeSecs) {
33-
CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder();
30+
Caffeine<Object, Object> builder = Caffeine.newBuilder();
3431
if (cacheExpirationTimeSecs >= 0) {
3532
builder.expireAfterWrite(cacheExpirationTimeSecs, TimeUnit.SECONDS);
3633
}
37-
tableMetadataCache =
38-
builder.build(
39-
new CacheLoader<TableKey, Optional<TableMetadata>>() {
40-
@Nonnull
41-
@Override
42-
public Optional<TableMetadata> load(@Nonnull TableKey key) throws Exception {
43-
return getTableMetadataFunc.apply(key);
44-
}
45-
});
34+
tableMetadataCache = builder.build(getTableMetadataFunc::apply);
4635
}
4736

4837
/**
@@ -61,22 +50,23 @@ public TableMetadata getTableMetadata(Operation operation) throws ExecutionExcep
6150
}
6251

6352
/**
64-
* Returns a table metadata corresponding to the specified operation.
53+
* Returns a table metadata corresponding to the specified namespace and table.
6554
*
6655
* @param namespace a namespace to retrieve
6756
* @param table a table to retrieve
6857
* @return a table metadata. null if the table is not found.
6958
* @throws ExecutionException if the operation fails
7059
*/
60+
@Nullable
7161
public TableMetadata getTableMetadata(String namespace, String table) throws ExecutionException {
7262
try {
7363
TableKey key = new TableKey(namespace, table);
74-
return tableMetadataCache.get(key).orElse(null);
75-
} catch (java.util.concurrent.ExecutionException e) {
64+
return tableMetadataCache.get(key);
65+
} catch (CompletionException e) {
7666
throw new ExecutionException(
7767
CoreError.GETTING_TABLE_METADATA_FAILED.buildMessage(
7868
ScalarDbUtils.getFullTableName(namespace, table)),
79-
e);
69+
e.getCause());
8070
}
8171
}
8272

core/src/main/java/com/scalar/db/transaction/consensuscommit/TransactionTableMetadataManager.java

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,39 @@
11
package com.scalar.db.transaction.consensuscommit;
22

3-
import com.google.common.cache.CacheBuilder;
4-
import com.google.common.cache.CacheLoader;
5-
import com.google.common.cache.LoadingCache;
3+
import com.github.benmanes.caffeine.cache.Caffeine;
4+
import com.github.benmanes.caffeine.cache.LoadingCache;
65
import com.scalar.db.api.DistributedStorageAdmin;
76
import com.scalar.db.api.Operation;
87
import com.scalar.db.api.TableMetadata;
98
import com.scalar.db.common.CoreError;
109
import com.scalar.db.exception.storage.ExecutionException;
1110
import com.scalar.db.util.ScalarDbUtils;
1211
import java.util.Objects;
13-
import java.util.Optional;
12+
import java.util.concurrent.CompletionException;
1413
import java.util.concurrent.TimeUnit;
15-
import javax.annotation.Nonnull;
1614
import javax.annotation.Nullable;
1715
import javax.annotation.concurrent.ThreadSafe;
1816

1917
@ThreadSafe
2018
public class TransactionTableMetadataManager {
2119

22-
private final LoadingCache<TableKey, Optional<TransactionTableMetadata>> tableMetadataCache;
20+
private final LoadingCache<TableKey, TransactionTableMetadata> tableMetadataCache;
2321

2422
public TransactionTableMetadataManager(
2523
DistributedStorageAdmin admin, long cacheExpirationTimeSecs) {
2624

27-
CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder();
25+
Caffeine<Object, Object> builder = Caffeine.newBuilder();
2826
if (cacheExpirationTimeSecs >= 0) {
2927
builder.expireAfterWrite(cacheExpirationTimeSecs, TimeUnit.SECONDS);
3028
}
3129
tableMetadataCache =
3230
builder.build(
33-
new CacheLoader<TableKey, Optional<TransactionTableMetadata>>() {
34-
@Nonnull
35-
@Override
36-
public Optional<TransactionTableMetadata> load(@Nonnull TableKey key)
37-
throws ExecutionException {
38-
TableMetadata tableMetadata = admin.getTableMetadata(key.namespace, key.table);
39-
if (tableMetadata == null) {
40-
return Optional.empty();
41-
}
42-
return Optional.of(new TransactionTableMetadata(tableMetadata));
31+
key -> {
32+
TableMetadata tableMetadata = admin.getTableMetadata(key.namespace, key.table);
33+
if (tableMetadata == null) {
34+
return null;
4335
}
36+
return new TransactionTableMetadata(tableMetadata);
4437
});
4538
}
4639

@@ -74,12 +67,12 @@ public TransactionTableMetadata getTransactionTableMetadata(String namespace, St
7467
throws ExecutionException {
7568
try {
7669
TableKey key = new TableKey(namespace, table);
77-
return tableMetadataCache.get(key).orElse(null);
78-
} catch (java.util.concurrent.ExecutionException e) {
70+
return tableMetadataCache.get(key);
71+
} catch (CompletionException e) {
7972
throw new ExecutionException(
8073
CoreError.GETTING_TABLE_METADATA_FAILED.buildMessage(
8174
ScalarDbUtils.getFullTableName(namespace, table)),
82-
e);
75+
e.getCause());
8376
}
8477
}
8578

0 commit comments

Comments
 (0)