Moved databases to sdcard.
Added InMemoryBlockStore android implementation.
This commit is contained in:
parent
232b25eb85
commit
7481fcc816
|
@ -61,7 +61,7 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
|||
options.logger(logger1);
|
||||
try {
|
||||
logger.debug("Opening database");
|
||||
File dbLocation = context.getDir(SystemProperties.CONFIG.databaseDir(), 0);
|
||||
File dbLocation = new File(SystemProperties.CONFIG.databaseDir());
|
||||
File fileLocation = new File(dbLocation, name);
|
||||
|
||||
if (SystemProperties.CONFIG.databaseReset()) {
|
||||
|
|
|
@ -31,4 +31,6 @@ public interface BlockStoreDatabase {
|
|||
public void save(TransactionReceiptVO transactionReceiptVO);
|
||||
|
||||
public TransactionReceipt getTransactionReceiptByHash(byte[] hash);
|
||||
|
||||
public boolean flush(List<Block> blocks);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ public class BlockStoreImpl implements BlockStore {
|
|||
|
||||
public Block getBlockByNumber(long blockNumber) {
|
||||
|
||||
|
||||
List result = database.getByNumber(blockNumber);
|
||||
if (result.size() == 0) return null;
|
||||
BlockVO vo = (BlockVO) result.get(0);
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
package org.ethereum.android.db;
|
||||
|
||||
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.TransactionReceipt;
|
||||
import org.ethereum.db.BlockStore;
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.math.BigInteger.ZERO;
|
||||
import static org.ethereum.util.ByteUtil.wrap;
|
||||
|
||||
|
||||
public class InMemoryBlockStore implements BlockStore {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger("general");
|
||||
|
||||
Map<ByteArrayWrapper, Block> hashIndex = new HashMap<>();
|
||||
Map<Long, Block> numberIndex = new HashMap<>();
|
||||
List<Block> blocks = new ArrayList<>();
|
||||
|
||||
private BlockStoreDatabase database;
|
||||
|
||||
BigInteger totalDifficulty = ZERO;
|
||||
|
||||
public InMemoryBlockStore(BlockStoreDatabase database) {
|
||||
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBlockHashByNumber(long blockNumber) {
|
||||
|
||||
Block block = numberIndex.get(blockNumber);
|
||||
|
||||
if (block == null)
|
||||
return dbGetBlockHashByNumber(blockNumber);
|
||||
else
|
||||
return block.getHash();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlockByNumber(long blockNumber) {
|
||||
|
||||
Block block = numberIndex.get(blockNumber);
|
||||
|
||||
if (block == null)
|
||||
return dbGetBlockByNumber(blockNumber);
|
||||
else
|
||||
return block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlockByHash(byte[] hash) {
|
||||
|
||||
Block block = hashIndex.get(wrap(hash));
|
||||
|
||||
if (block == null)
|
||||
return dbGetBlockByHash(hash);
|
||||
else
|
||||
return block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getListOfHashesStartFrom(byte[] hash, int qty) {
|
||||
|
||||
Block startBlock = hashIndex.get(wrap(hash));
|
||||
|
||||
long endIndex = startBlock.getNumber() + qty;
|
||||
endIndex = getBestBlock().getNumber() < endIndex ? getBestBlock().getNumber() : endIndex;
|
||||
|
||||
List<byte[]> hashes = new ArrayList<>();
|
||||
|
||||
for (long i = startBlock.getNumber(); i <= endIndex; ++i){
|
||||
Block block = getBlockByNumber(i);
|
||||
hashes.add(block.getHash() );
|
||||
}
|
||||
|
||||
return hashes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteBlocksSince(long number) {
|
||||
|
||||
// todo: delete blocks sinse
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveBlock(Block block, List<TransactionReceipt> receipts) {
|
||||
ByteArrayWrapper wHash = wrap(block.getHash());
|
||||
blocks.add(block);
|
||||
hashIndex.put(wHash, block);
|
||||
numberIndex.put(block.getNumber(), block);
|
||||
totalDifficulty = totalDifficulty.add(block.getCumulativeDifficulty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getTotalDifficultySince(long number) {
|
||||
|
||||
// todo calculate from db + from cache
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getTotalDifficulty() {
|
||||
return totalDifficulty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBestBlock() {
|
||||
if (blocks.size() == 0) return null;
|
||||
return blocks.get(blocks.size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Block> getAllBlocks() {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
blocks.clear();
|
||||
hashIndex.clear();
|
||||
numberIndex.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionReceipt getTransactionReceiptByHash(byte[] hash) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// FIXME: wrap from here in to db class
|
||||
|
||||
public byte[] dbGetBlockHashByNumber(long blockNumber) {
|
||||
|
||||
Block block = getBlockByNumber(blockNumber);
|
||||
if (block != null) return block.getHash();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Block dbGetBlockByNumber(long blockNumber) {
|
||||
|
||||
List result = database.getByNumber(blockNumber);
|
||||
if (result.size() == 0) return null;
|
||||
BlockVO vo = (BlockVO) result.get(0);
|
||||
|
||||
return new Block(vo.rlp);
|
||||
}
|
||||
|
||||
public Block dbGetBlockByHash(byte[] hash) {
|
||||
|
||||
List result = database.getByHash(hash);
|
||||
|
||||
if (result.size() == 0) return null;
|
||||
BlockVO vo = (BlockVO) result.get(0);
|
||||
|
||||
return new Block(vo.rlp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush(){
|
||||
|
||||
long t_ = System.nanoTime();
|
||||
|
||||
database.flush(blocks);
|
||||
Block block = getBestBlock();
|
||||
|
||||
blocks.clear();
|
||||
hashIndex.clear();
|
||||
numberIndex.clear();
|
||||
|
||||
saveBlock(block, null);
|
||||
|
||||
long t__ = System.nanoTime();
|
||||
logger.info("Flush block store in: {} ms", ((float) (t__ - t_) / 1_000_000));
|
||||
|
||||
totalDifficulty = (BigInteger) database.getTotalDifficulty();
|
||||
}
|
||||
|
||||
public void load(){
|
||||
|
||||
logger.info("loading db");
|
||||
|
||||
long t = System.nanoTime();
|
||||
|
||||
Block bestBlock = database.getBestBlock();
|
||||
if (bestBlock == null) return;
|
||||
saveBlock(bestBlock, null);
|
||||
|
||||
totalDifficulty = database.getTotalDifficulty();
|
||||
|
||||
long t_ = System.nanoTime();
|
||||
|
||||
logger.info("Loaded db in: {} ms", ((float)(t_ - t) / 1_000_000));
|
||||
}
|
||||
|
||||
}
|
|
@ -2,11 +2,13 @@ package org.ethereum.android.db;
|
|||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
import com.j256.ormlite.dao.GenericRawResults;
|
||||
import com.j256.ormlite.misc.TransactionManager;
|
||||
import com.j256.ormlite.stmt.DeleteBuilder;
|
||||
import com.j256.ormlite.support.ConnectionSource;
|
||||
import com.j256.ormlite.table.TableUtils;
|
||||
|
@ -14,10 +16,12 @@ import com.j256.ormlite.table.TableUtils;
|
|||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.TransactionReceipt;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implements BlockStoreDatabase {
|
||||
|
||||
|
@ -28,7 +32,8 @@ public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implement
|
|||
private Dao<TransactionReceiptVO, Integer> transactionDao = null;
|
||||
|
||||
public OrmLiteBlockStoreDatabase(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
super(context, Environment.getExternalStorageDirectory().getAbsolutePath()
|
||||
+ File.separator + DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -252,4 +257,27 @@ public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implement
|
|||
return new TransactionReceipt(vo.rlp);
|
||||
|
||||
}
|
||||
|
||||
public boolean flush(final List<Block> blocks) {
|
||||
|
||||
try {
|
||||
TransactionManager.callInTransaction(getBlockDao().getConnectionSource(),
|
||||
new Callable<Void>() {
|
||||
public Void call() throws Exception {
|
||||
for (Block block : blocks) {
|
||||
BlockVO blockVO = new BlockVO(block.getNumber(), block.getHash(), block.getEncoded(), block.getCumulativeDifficulty());
|
||||
save(blockVO);
|
||||
}
|
||||
// you could pass back an object here
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return true;
|
||||
} catch(java.sql.SQLException e) {
|
||||
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error querying for hash", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Context;
|
|||
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||
|
||||
import org.ethereum.android.datasource.LevelDbDataSource;
|
||||
import org.ethereum.android.db.InMemoryBlockStore;
|
||||
import org.ethereum.android.db.OrmLiteBlockStoreDatabase;
|
||||
import org.ethereum.android.db.BlockStoreImpl;
|
||||
import org.ethereum.config.SystemProperties;
|
||||
|
@ -76,7 +77,7 @@ public class EthereumModule {
|
|||
@Singleton
|
||||
BlockStore provideBlockStore() {
|
||||
OrmLiteBlockStoreDatabase database = OpenHelperManager.getHelper(context, OrmLiteBlockStoreDatabase.class);
|
||||
return new BlockStoreImpl(database);
|
||||
return new InMemoryBlockStore(database);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -90,7 +90,7 @@ samples.dir = samples
|
|||
database.reset = false
|
||||
|
||||
# place to save physical storage files
|
||||
database.dir = database
|
||||
database.dir = /mnt/sdcard
|
||||
|
||||
# this string is computed
|
||||
# to be eventually the address
|
||||
|
|
Loading…
Reference in New Issue