-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feature(db): optimize properties query frequency #5378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1999fe2
79ca721
5201ddb
59c5fe8
dced678
a66f807
3b40771
1ae4a53
2ca5129
180b26f
a8a7492
cc053b7
9430e13
0f86735
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -221,6 +221,12 @@ public synchronized void commit() { | |
} | ||
|
||
--activeSession; | ||
|
||
dbs.forEach(db -> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why set the reload logic in Are there other reasons for doing this, can you explain? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is because if the transaction ends without a commit, |
||
if (db.getHead().isOptimized()) { | ||
db.getHead().reloadToMem(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isOptimized judged twice There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK,I get it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have fixed this |
||
} | ||
}); | ||
} | ||
|
||
public synchronized void pop() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
package org.tron.core.db2; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNull; | ||
|
||
import java.io.File; | ||
import java.lang.reflect.Constructor; | ||
import org.junit.After; | ||
import org.junit.Assert; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.tron.common.application.Application; | ||
import org.tron.common.application.ApplicationFactory; | ||
import org.tron.common.application.TronApplicationContext; | ||
import org.tron.common.utils.FileUtil; | ||
import org.tron.core.Constant; | ||
import org.tron.core.config.DefaultConfig; | ||
import org.tron.core.config.args.Args; | ||
import org.tron.core.db2.core.Snapshot; | ||
import org.tron.core.db2.core.SnapshotImpl; | ||
import org.tron.core.db2.core.SnapshotManager; | ||
import org.tron.core.db2.core.SnapshotRoot; | ||
|
||
public class SnapshotImplTest { | ||
private RevokingDbWithCacheNewValueTest.TestRevokingTronStore tronDatabase; | ||
private TronApplicationContext context; | ||
private Application appT; | ||
private SnapshotManager revokingDatabase; | ||
|
||
@Before | ||
public void init() { | ||
Args.setParam(new String[]{"-d", "output_revokingStore_test"}, Constant.TEST_CONF); | ||
context = new TronApplicationContext(DefaultConfig.class); | ||
appT = ApplicationFactory.create(context); | ||
|
||
tronDatabase = new RevokingDbWithCacheNewValueTest.TestRevokingTronStore( | ||
"testSnapshotRoot-testMerge"); | ||
revokingDatabase = context.getBean(SnapshotManager.class); | ||
revokingDatabase.enable(); | ||
revokingDatabase.add(tronDatabase.getRevokingDB()); | ||
} | ||
|
||
@After | ||
public void removeDb() { | ||
Args.clearParam(); | ||
context.destroy(); | ||
FileUtil.deleteDir(new File("output_revokingStore_test")); | ||
|
||
tronDatabase.close(); | ||
revokingDatabase.shutdown(); | ||
} | ||
|
||
/** | ||
* linklist is: from -> root | ||
* root:key1=>value1, key2=>value2 | ||
* from:key3=>value3, key4=>value4 | ||
* after construct, getSnapshotImplIns(root); | ||
* from: key1=>value1, key2=>value2, key3=>value3, key4=>value4 | ||
* from: get key1 or key2, traverse 0 times | ||
*/ | ||
@Test | ||
public void testMergeRoot() { | ||
// linklist is: from -> root | ||
SnapshotRoot root = new SnapshotRoot(tronDatabase.getDb()); | ||
//root.setOptimized(true); | ||
|
||
root.put("key1".getBytes(), "value1".getBytes()); | ||
root.put("key2".getBytes(), "value2".getBytes()); | ||
SnapshotImpl from = getSnapshotImplIns(root); | ||
from.put("key3".getBytes(), "value3".getBytes()); | ||
from.put("key4".getBytes(), "value4".getBytes()); | ||
|
||
byte[] s1 = from.get("key1".getBytes()); | ||
assertEquals(new String("value1".getBytes()), new String(s1)); | ||
byte[] s2 = from.get("key2".getBytes()); | ||
assertEquals(new String("value2".getBytes()), new String(s2)); | ||
} | ||
|
||
/** | ||
* linklist is: from2 -> from -> root | ||
* root: | ||
* from:key1=>value1, key2=>value2 | ||
* from2:key3=>value3,key4=>value4 | ||
* before merge: from2.mergeAhead(from); | ||
* from2: get key1 or key2, traverse 1 times | ||
* after merge | ||
* from2:key1=>value1, key2=>value2, value3=>value3,key4=>value4 | ||
* from2: get key1 or key2, traverse 0 times | ||
* | ||
*/ | ||
@Test | ||
public void testMergeAhead() { | ||
|
||
// linklist is: from2 -> from -> root | ||
SnapshotRoot root = new SnapshotRoot(tronDatabase.getDb()); | ||
SnapshotImpl from = getSnapshotImplIns(root); | ||
from.put("key1".getBytes(), "value1".getBytes()); | ||
from.put("key2".getBytes(), "value2".getBytes()); | ||
|
||
SnapshotImpl from2 = getSnapshotImplIns(from); | ||
from2.put("key3".getBytes(), "value3".getBytes()); | ||
from2.put("key4".getBytes(), "value4".getBytes()); | ||
|
||
/* | ||
// before merge get data in from is success,traverse 0 times | ||
byte[] s1 = from.get("key1".getBytes()); | ||
assertEquals(new String("value1".getBytes()), new String(s1)); | ||
byte[] s2 = from.get("key2".getBytes()); | ||
assertEquals(new String("value2".getBytes()), new String(s2)); | ||
// before merge get data in from2 is success, traverse 0 times | ||
byte[] s3 = from2.get("key3".getBytes()); | ||
assertEquals(new String("value3".getBytes()), new String(s3)); | ||
byte[] s4 = from2.get("key4".getBytes()); | ||
assertEquals(new String("value4".getBytes()), new String(s4)); | ||
*/ | ||
|
||
// before merge from2 get data is success, traverse 1 times | ||
byte[] s11 = from2.get("key1".getBytes()); | ||
assertEquals(new String("value1".getBytes()), new String(s11)); | ||
byte[] s12 = from2.get("key2".getBytes()); | ||
assertEquals(new String("value2".getBytes()), new String(s12)); | ||
// this can not get key3 and key4 | ||
assertNull(from.get("key3".getBytes())); | ||
assertNull(from.get("key4".getBytes())); | ||
|
||
// do mergeAhead | ||
from2.mergeAhead(from); | ||
/* | ||
// after merge get data in from is success, traverse 0 times | ||
s1 = from.get("key1".getBytes()); | ||
assertEquals(new String("value1".getBytes()), new String(s1)); | ||
s2 = from.get("key2".getBytes()); | ||
assertEquals(new String("value2".getBytes()), new String(s2)); | ||
|
||
// after merge get data in from2 is success, traverse 0 times | ||
s3 = from2.get("key3".getBytes()); | ||
assertEquals(new String("value3".getBytes()), new String(s3)); | ||
s4 = from2.get("key4".getBytes()); | ||
assertEquals(new String("value4".getBytes()), new String(s4)); | ||
*/ | ||
|
||
// after merge from2 get data is success, traverse 0 times | ||
byte[] s1 = from2.get("key1".getBytes()); | ||
assertEquals(new String("value1".getBytes()), new String(s1)); | ||
byte[] s2 = from2.get("key2".getBytes()); | ||
assertEquals(new String("value2".getBytes()), new String(s2)); | ||
|
||
// this can not get key3 and key4 | ||
assertNull(from.get("key3".getBytes())); | ||
assertNull(from.get("key4".getBytes())); | ||
} | ||
|
||
/** | ||
* from: key1=>value1, key2=>value2, key3=>value31 | ||
* from2: key3=>value32,key4=>value4 | ||
* after merge: from2.mergeAhead(from); | ||
* from2: key1=>value1, key2=>value2, key3=>value32, key4=>value4 | ||
*/ | ||
@Test | ||
public void testMergeOverride() { | ||
// linklist is: from2 -> from -> root | ||
SnapshotRoot root = new SnapshotRoot(tronDatabase.getDb()); | ||
SnapshotImpl from = getSnapshotImplIns(root); | ||
from.put("key1".getBytes(), "value1".getBytes()); | ||
from.put("key2".getBytes(), "value2".getBytes()); | ||
from.put("key3".getBytes(), "value31".getBytes()); | ||
|
||
SnapshotImpl from2 = getSnapshotImplIns(from); | ||
from2.put("key3".getBytes(), "value32".getBytes()); | ||
from2.put("key4".getBytes(), "value4".getBytes()); | ||
// do mergeAhead | ||
from2.mergeAhead(from); | ||
|
||
// after merge from2 get data is success, traverse 0 times | ||
byte[] s1 = from2.get("key1".getBytes()); | ||
assertEquals(new String("value1".getBytes()), new String(s1)); | ||
byte[] s2 = from2.get("key2".getBytes()); | ||
assertEquals(new String("value2".getBytes()), new String(s2)); | ||
byte[] s3 = from2.get("key3".getBytes()); | ||
assertEquals(new String("value32".getBytes()), new String(s3)); | ||
byte[] s4 = from2.get("key4".getBytes()); | ||
assertEquals(new String("value4".getBytes()), new String(s4)); | ||
} | ||
|
||
/** | ||
* The constructor of SnapshotImpl is not public | ||
* so reflection is used to construct the object here. | ||
*/ | ||
private SnapshotImpl getSnapshotImplIns(Snapshot snapshot) { | ||
Class clazz = SnapshotImpl.class; | ||
try { | ||
Constructor constructor = clazz.getDeclaredConstructor(Snapshot.class); | ||
constructor.setAccessible(true); | ||
return (SnapshotImpl) constructor.newInstance(snapshot); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
return null; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why reserve these if they are useless?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed this part of the commented code