Skip to content

Commit fd1d0f1

Browse files
committed
feat(*): improve performance
1. add second-cache for revoking db 2. optimize pack trx
1 parent 2d88f6e commit fd1d0f1

File tree

16 files changed

+357
-61
lines changed

16 files changed

+357
-61
lines changed

chainbase/src/main/java/org/tron/core/capsule/BlockCapsule.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ public void addTransaction(TransactionCapsule pendingTrx) {
143143
getTransactions().add(pendingTrx);
144144
}
145145

146+
public void addAllTransactions(List<TransactionCapsule> pendingTrxs) {
147+
List<Transaction> list = pendingTrxs.stream().map(TransactionCapsule::getInstance).collect(
148+
Collectors.toList());
149+
this.block = this.block.toBuilder().addAllTransactions(list).build();
150+
getTransactions().addAll(pendingTrxs);
151+
}
152+
146153
public List<TransactionCapsule> getTransactions() {
147154
return transactions;
148155
}

chainbase/src/main/java/org/tron/core/capsule/TransactionRetCapsule.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.tron.core.capsule;
22

33
import com.google.protobuf.InvalidProtocolBufferException;
4+
import java.util.List;
45
import java.util.Objects;
56
import lombok.extern.slf4j.Slf4j;
67
import org.tron.core.exception.BadItemException;
@@ -29,7 +30,7 @@ public TransactionRetCapsule() {
2930

3031
public TransactionRetCapsule(byte[] data) throws BadItemException {
3132
try {
32-
this.transactionRet = transactionRet.parseFrom(data);
33+
this.transactionRet = TransactionRet.parseFrom(data);
3334
} catch (InvalidProtocolBufferException e) {
3435
throw new BadItemException("TransactionInfoCapsule proto data parse exception");
3536
}
@@ -39,6 +40,10 @@ public void addTransactionInfo(TransactionInfo result) {
3940
this.transactionRet = this.transactionRet.toBuilder().addTransactioninfo(result).build();
4041
}
4142

43+
public void addAllTransactionInfos(List<TransactionInfo> results) {
44+
this.transactionRet = this.transactionRet.toBuilder().addAllTransactioninfo(results).build();
45+
}
46+
4247
@Override
4348
public byte[] getData() {
4449
if (Objects.isNull(transactionRet)) {

chainbase/src/main/java/org/tron/core/db2/common/DB.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public interface DB<K, V> extends Iterable<Map.Entry<K, V>>, Instance<DB<K, V>>
1515

1616
void remove(K k);
1717

18-
Iterator iterator();
18+
Iterator<Map.Entry<K, V>> iterator();
1919

2020
void close();
2121

chainbase/src/main/java/org/tron/core/db2/core/AbstractSnapshot.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ public abstract class AbstractSnapshot<K, V> implements Snapshot {
1515

1616
protected WeakReference<Snapshot> next;
1717

18-
protected boolean isOptimized;
19-
2018
@Override
2119
public Snapshot advance() {
2220
return new SnapshotImpl(this);
@@ -36,9 +34,4 @@ public void setNext(Snapshot next) {
3634
public String getDbName() {
3735
return db.getDbName();
3836
}
39-
40-
@Override
41-
public boolean isOptimized(){
42-
return isOptimized;
43-
}
4437
}

chainbase/src/main/java/org/tron/core/db2/core/Snapshot.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,4 @@ static boolean isImpl(Snapshot snapshot) {
4646
void updateSolidity();
4747

4848
String getDbName();
49-
50-
boolean isOptimized();
5149
}

chainbase/src/main/java/org/tron/core/db2/core/SnapshotImpl.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,6 @@ public class SnapshotImpl extends AbstractSnapshot<Key, Value> {
3030
}
3131
previous = snapshot;
3232
snapshot.setNext(this);
33-
// inherit
34-
isOptimized = snapshot.isOptimized();
35-
// merge for DynamicPropertiesStore,about 100 keys
36-
if (isOptimized) {
37-
if (root == previous ){
38-
Streams.stream(root.iterator()).forEach( e -> put(e.getKey(),e.getValue()));
39-
}else {
40-
merge(previous);
41-
}
42-
}
4333
}
4434

4535
@Override
@@ -50,10 +40,6 @@ public byte[] get(byte[] key) {
5040
private byte[] get(Snapshot head, byte[] key) {
5141
Snapshot snapshot = head;
5242
Value value;
53-
if (isOptimized) {
54-
value = db.get(Key.of(key));
55-
return value == null ? null: value.getBytes();
56-
}
5743
while (Snapshot.isImpl(snapshot)) {
5844
if ((value = ((SnapshotImpl) snapshot).db.get(Key.of(key))) != null) {
5945
return value.getBytes();

chainbase/src/main/java/org/tron/core/db2/core/SnapshotRoot.java

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
package org.tron.core.db2.core;
22

3-
import ch.qos.logback.core.encoder.ByteArrayUtil;
43
import com.google.common.collect.Maps;
54
import com.google.common.collect.Streams;
65
import java.util.HashMap;
76
import java.util.Iterator;
87
import java.util.List;
98
import java.util.Map;
9+
import java.util.Objects;
1010
import java.util.stream.Collectors;
1111
import lombok.Getter;
12+
import org.tron.common.cache.CacheManager;
13+
import org.tron.common.cache.TronCache;
14+
import org.tron.common.parameter.CommonParameter;
1215
import org.tron.common.utils.ByteArray;
1316
import org.tron.core.ChainBaseManager;
1417
import org.tron.core.capsule.AccountCapsule;
@@ -23,11 +26,17 @@ public class SnapshotRoot extends AbstractSnapshot<byte[], byte[]> {
2326
private Snapshot solidity;
2427
private boolean isAccountDB;
2528

29+
private TronCache<WrappedByteArray, WrappedByteArray> cache;
30+
private static final List<String> CACHE_DBS = CommonParameter.getInstance()
31+
.getStorage().getCacheDbs();
32+
2633
public SnapshotRoot(DB<byte[], byte[]> db) {
2734
this.db = db;
2835
solidity = this;
29-
isOptimized = "properties".equalsIgnoreCase(db.getDbName());
3036
isAccountDB = "account".equalsIgnoreCase(db.getDbName());
37+
if (CACHE_DBS.contains(this.db.getDbName())) {
38+
this.cache = CacheManager.allocate(this.db.getDbName());
39+
}
3140
}
3241

3342
private boolean needOptAsset() {
@@ -37,11 +46,18 @@ private boolean needOptAsset() {
3746

3847
@Override
3948
public byte[] get(byte[] key) {
40-
return db.get(key);
49+
WrappedByteArray cache = getCache(key);
50+
if (cache != null) {
51+
return cache.getBytes();
52+
}
53+
byte[] value = db.get(key);
54+
putCache(key, value);
55+
return value;
4156
}
4257

4358
@Override
4459
public void put(byte[] key, byte[] value) {
60+
byte[] v = value;
4561
if (needOptAsset()) {
4662
if (ByteArray.isEmpty(value)) {
4763
remove(key);
@@ -56,10 +72,10 @@ public void put(byte[] key, byte[] value) {
5672
}
5773
assetStore.putAccount(item.getInstance());
5874
item.clearAsset();
59-
db.put(key, item.getData());
60-
} else {
61-
db.put(key, value);
75+
v = item.getData();
6276
}
77+
db.put(key, v);
78+
putCache(key, v);
6379
}
6480

6581
@Override
@@ -68,6 +84,7 @@ public void remove(byte[] key) {
6884
ChainBaseManager.getInstance().getAccountAssetStore().deleteAccount(key);
6985
}
7086
db.remove(key);
87+
putCache(key, null);
7188
}
7289

7390
@Override
@@ -81,6 +98,7 @@ public void merge(Snapshot from) {
8198
processAccount(batch);
8299
} else {
83100
((Flusher) db).flush(batch);
101+
putCache(batch);
84102
}
85103
}
86104

@@ -97,6 +115,7 @@ public void merge(List<Snapshot> snapshots) {
97115
processAccount(batch);
98116
} else {
99117
((Flusher) db).flush(batch);
118+
putCache(batch);
100119
}
101120
}
102121

@@ -120,11 +139,37 @@ private void processAccount(Map<WrappedByteArray, WrappedByteArray> batch) {
120139
}
121140
});
122141
((Flusher) db).flush(accounts);
142+
putCache(accounts);
123143
if (assets.size() > 0) {
124144
assetStore.updateByBatch(AccountAssetStore.convert(assets));
125145
}
126146
}
127147

148+
private boolean cached() {
149+
return Objects.nonNull(this.cache);
150+
}
151+
152+
private void putCache(byte[] key, byte[] value) {
153+
if (cached()) {
154+
cache.put(WrappedByteArray.of(key), WrappedByteArray.of(value));
155+
}
156+
}
157+
158+
private void putCache(Map<WrappedByteArray, WrappedByteArray> values) {
159+
if (cached()) {
160+
values.forEach(cache::put);
161+
}
162+
}
163+
164+
private WrappedByteArray getCache(byte[] key) {
165+
if (cached()) {
166+
return cache.getIfPresent(WrappedByteArray.of(key));
167+
}
168+
return null;
169+
}
170+
171+
// second cache
172+
128173
@Override
129174
public Snapshot retreat() {
130175
return this;
@@ -142,11 +187,13 @@ public Iterator<Map.Entry<byte[], byte[]>> iterator() {
142187

143188
@Override
144189
public void close() {
190+
CacheManager.release(this.getDbName());
145191
((Flusher) db).close();
146192
}
147193

148194
@Override
149195
public void reset() {
196+
CacheManager.release(this.getDbName());
150197
((Flusher) db).reset();
151198
}
152199

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.tron.common.cache;
2+
3+
import com.google.common.cache.CacheLoader;
4+
import com.google.common.cache.CacheStats;
5+
import com.google.common.collect.Maps;
6+
import java.util.Map;
7+
import java.util.stream.Collectors;
8+
import org.tron.common.parameter.CommonParameter;
9+
10+
public class CacheManager {
11+
12+
private static final Map<String, TronCache<?, ?>> CACHES = Maps.newConcurrentMap();
13+
14+
public static <K, V> TronCache<K, V> allocate(String name) {
15+
TronCache<K, V> cache = new TronCache<>(name, CommonParameter.getInstance()
16+
.getStorage().getCacheStrategy(name));
17+
CACHES.put(name, cache);
18+
return cache;
19+
}
20+
21+
public static <K, V> TronCache<K, V> allocate(String name, String strategy) {
22+
TronCache<K, V> cache = new TronCache<>(name, strategy);
23+
CACHES.put(name, cache);
24+
return cache;
25+
}
26+
27+
public static <K, V> TronCache<K, V> allocate(String name, String strategy,
28+
CacheLoader<K, V> loader) {
29+
TronCache<K, V> cache = new TronCache<>(name, strategy, loader);
30+
CACHES.put(name, cache);
31+
return cache;
32+
}
33+
34+
public static void release(String name) {
35+
TronCache cache = CACHES.remove(name);
36+
if (cache != null) {
37+
cache.invalidateAll();
38+
}
39+
}
40+
41+
public static Map<String, CacheStats> stats() {
42+
return CACHES.values().stream().collect(Collectors.toMap(TronCache::getName, TronCache::stats));
43+
}
44+
45+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package org.tron.common.cache;
2+
3+
import com.google.common.base.Objects;
4+
import com.google.common.cache.Cache;
5+
import com.google.common.cache.CacheBuilder;
6+
import com.google.common.cache.CacheLoader;
7+
import com.google.common.cache.CacheStats;
8+
import java.util.concurrent.Callable;
9+
import java.util.concurrent.ExecutionException;
10+
import lombok.Getter;
11+
12+
public class TronCache<K, V> {
13+
14+
private static final int CPUS = Runtime.getRuntime().availableProcessors();
15+
16+
@Getter
17+
private final String name;
18+
private final Cache<K, V> cache;
19+
20+
TronCache(String name, String strategy) {
21+
this.name = name;
22+
this.cache = CacheBuilder.from(strategy).concurrencyLevel(CPUS).recordStats().build();
23+
}
24+
25+
TronCache(String name, String strategy, CacheLoader<K, V> loader) {
26+
this.name = name;
27+
this.cache = CacheBuilder.from(strategy).concurrencyLevel(CPUS).recordStats().build(loader);
28+
}
29+
30+
public void put(K k, V v) {
31+
this.cache.put(k, v);
32+
}
33+
34+
public V getIfPresent(K k) {
35+
return this.cache.getIfPresent(k);
36+
}
37+
38+
public V get(K k, Callable<? extends V> loader) throws ExecutionException {
39+
return this.cache.get(k, loader);
40+
}
41+
42+
public CacheStats stats() {
43+
return this.cache.stats();
44+
}
45+
46+
public void invalidateAll() {
47+
this.cache.invalidateAll();
48+
}
49+
50+
@Override
51+
public boolean equals(Object o) {
52+
if (this == o) {
53+
return true;
54+
}
55+
if (o == null || getClass() != o.getClass()) {
56+
return false;
57+
}
58+
TronCache<?, ?> tronCache = (TronCache<?, ?>) o;
59+
return Objects.equal(name, tronCache.name);
60+
}
61+
62+
@Override
63+
public int hashCode() {
64+
return Objects.hashCode(name);
65+
}
66+
}

0 commit comments

Comments
 (0)