Merge branch 'android-test-poc9-rlpx' of https://opulence.git.beanstalkapp.com/ethereumj into android-test-poc9-rlpx
This commit is contained in:
commit
6c53a30ac6
|
@ -21,6 +21,7 @@ android {
|
|||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
multiDexEnabled true
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
|
@ -54,7 +55,12 @@ dependencies {
|
|||
compile project(':ethereumj-core-android')
|
||||
compile 'com.android.support:multidex:1.0.0'
|
||||
compile fileTree(include: ['*.jar'], dir: '../libraries')
|
||||
compile 'com.android.support:support-v4:22.1.1'
|
||||
compile 'com.android.support:appcompat-v7:22.1.1'
|
||||
compile 'com.android.support:recyclerview-v7:22.1.1'
|
||||
compile 'com.android.support:support-v4:22.2.0'
|
||||
compile 'com.android.support:appcompat-v7:22.2.0'
|
||||
compile 'com.android.support:recyclerview-v7:22.2.0'
|
||||
|
||||
androidTestCompile 'com.android.support.test:runner:0.3'
|
||||
// Set this dependency to use JUnit 4 rules
|
||||
androidTestCompile 'com.android.support.test:rules:0.3'
|
||||
|
||||
}
|
|
@ -0,0 +1,311 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||
|
||||
import org.ethereum.android.db.OrmLiteBlockStoreDatabase;
|
||||
import org.ethereum.android.util.Scanner;
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.db.BlockStore;
|
||||
import org.ethereum.android.db.InMemoryBlockStore;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.math.BigInteger.ZERO;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class InMemoryBlockStoreTest extends ActivityInstrumentationTestCase2<TestActivity> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||
|
||||
private static boolean loaded = false;
|
||||
|
||||
private TestActivity activity;
|
||||
private List<Block> blocks = new ArrayList<>();
|
||||
private OrmLiteBlockStoreDatabase database;
|
||||
|
||||
public InMemoryBlockStoreTest() {
|
||||
|
||||
super(TestActivity.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
super.setUp();
|
||||
loaded = false;
|
||||
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
|
||||
activity = getActivity();
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getTargetContext().getAssets().open("blockstore");
|
||||
final Scanner scanner = new Scanner(inputStream);
|
||||
ThreadGroup group = new ThreadGroup("threadGroup");
|
||||
new Thread(group, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
logger.info("Loading blocks.");
|
||||
|
||||
BigInteger cumDifficulty = ZERO;
|
||||
|
||||
while (scanner.hasNext()) {
|
||||
|
||||
String blockString = scanner.nextLine();
|
||||
|
||||
logger.info("BlockString: " + blockString);
|
||||
try {
|
||||
Block block = new Block(
|
||||
Hex.decode(blockString));
|
||||
//if (block.getNumber() % 1000 == 0)
|
||||
logger.info("adding block.hash: [{}] block.number: [{}]",
|
||||
block.getShortHash(),
|
||||
block.getNumber());
|
||||
|
||||
blocks.add(block);
|
||||
cumDifficulty = cumDifficulty.add(block.getCumulativeDifficulty());
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("total difficulty: {}", cumDifficulty);
|
||||
InMemoryBlockStoreTest.loaded = true;
|
||||
}
|
||||
}, "EthereumConnect", 32768000).start();
|
||||
|
||||
|
||||
database = OpenHelperManager.getHelper(activity, OrmLiteBlockStoreDatabase.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet0() {
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
assertThat(activity, notNullValue());
|
||||
assertThat(getInstrumentation(), notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty(){
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
assertNull(blockStore.getBestBlock());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFlush(){
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
blockStore.flush();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleLoad(){
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
blockStore.flush();
|
||||
|
||||
blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
blockStore.load();
|
||||
|
||||
assertTrue(blockStore.getBestBlock().getNumber() == 8003);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFlushEach1000(){
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
InMemoryBlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( int i = 0; i < blocks.size(); ++i ){
|
||||
|
||||
blockStore.saveBlock(blocks.get(i), null);
|
||||
if ( i % 1000 == 0){
|
||||
blockStore.flush();
|
||||
assertTrue(blockStore.blocks.size() == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBlockHashByNumber(){
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
String hash = Hex.toHexString(blockStore.getBlockHashByNumber(7000));
|
||||
assertTrue(hash.startsWith("459a8f"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockHashByNumber(6000));
|
||||
assertTrue(hash.startsWith("7a577a"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockHashByNumber(5000));
|
||||
assertTrue(hash.startsWith("820aa7"));
|
||||
|
||||
blockStore.flush();
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockHashByNumber(7000));
|
||||
assertTrue(hash.startsWith("459a8f"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockHashByNumber(6000));
|
||||
assertTrue(hash.startsWith("7a577a"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockHashByNumber(5000));
|
||||
assertTrue(hash.startsWith("820aa7"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockByNumber(){
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
String hash = Hex.toHexString(blockStore.getBlockByNumber(7000).getHash());
|
||||
assertTrue(hash.startsWith("459a8f"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockByNumber(6000).getHash());
|
||||
assertTrue(hash.startsWith("7a577a"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockByNumber(5000).getHash());
|
||||
assertTrue(hash.startsWith("820aa7"));
|
||||
|
||||
blockStore.flush();
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockByNumber(7000).getHash());
|
||||
assertTrue(hash.startsWith("459a8f"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockByNumber(6000).getHash());
|
||||
assertTrue(hash.startsWith("7a577a"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockByNumber(5000).getHash());
|
||||
assertTrue(hash.startsWith("820aa7"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetBlockByNumber() {
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
assertEquals("4312750101", blockStore.getTotalDifficulty().toString());
|
||||
|
||||
blockStore.flush();
|
||||
assertEquals("4312750101", blockStore.getTotalDifficulty().toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDbGetBlockByHash(){
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
byte[] hash7000 = Hex.decode("459a8f0ee5d4b0c9ea047797606c94f0c1158ed0f30120490b96f7df9893e1fa");
|
||||
byte[] hash6000 = Hex.decode("7a577a6b0b7e72e51a646c4cec82cf684c977bca6307e2a49a4116af49316159");
|
||||
byte[] hash5000 = Hex.decode("820aa786619e1a2ae139877ba342078c83e5bd65c559069336c13321441e03dc");
|
||||
|
||||
Long number = blockStore.getBlockByHash(hash7000).getNumber();
|
||||
assertTrue(number == 7000);
|
||||
|
||||
number = blockStore.getBlockByHash(hash6000).getNumber();
|
||||
assertTrue(number == 6000);
|
||||
|
||||
number = blockStore.getBlockByHash(hash5000).getNumber();
|
||||
assertTrue(number == 5000);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@Ignore // TO much time to run it on general basis
|
||||
@Test
|
||||
public void save100KBlocks() throws FileNotFoundException {
|
||||
|
||||
String blocksFile = "E:\\temp\\_poc-9-blocks\\poc-9-492k.dmp";
|
||||
|
||||
FileInputStream inputStream = new FileInputStream(blocksFile);
|
||||
Scanner scanner = new Scanner(inputStream, "UTF-8");
|
||||
|
||||
BlockStore blockStore = new InMemoryBlockStore();
|
||||
//blockStore.setSessionFactory(sessionFactory());
|
||||
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
|
||||
byte[] blockRLPBytes = Hex.decode( scanner.nextLine());
|
||||
Block block = new Block(blockRLPBytes);
|
||||
|
||||
System.out.println(block.getNumber());
|
||||
|
||||
blockStore.saveBlock(block, null);
|
||||
|
||||
if (block.getNumber() > 100_000) break;
|
||||
}
|
||||
|
||||
blockStore.flush();
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.os.Environment;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
|
||||
import org.ethereum.android.datasource.LevelDbDataSource;
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.datasource.KeyValueDataSource;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class LevelDbDataSourceTest extends ActivityInstrumentationTestCase2<TestActivity> {
|
||||
|
||||
private TestActivity activity;
|
||||
|
||||
public LevelDbDataSourceTest() {
|
||||
|
||||
super(TestActivity.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
super.setUp();
|
||||
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
|
||||
activity = getActivity();
|
||||
System.setProperty("sun.arch.data.model", "32");
|
||||
System.setProperty("leveldb.mmap", "false");
|
||||
String databaseFolder = null;
|
||||
File extStore = Environment.getExternalStorageDirectory();
|
||||
if (extStore.exists()) {
|
||||
databaseFolder = extStore.getAbsolutePath();
|
||||
} else {
|
||||
databaseFolder = activity.getApplicationInfo().dataDir;
|
||||
}
|
||||
if (databaseFolder != null) {
|
||||
System.out.println("Database folder: " + databaseFolder);
|
||||
SystemProperties.CONFIG.setDataBaseDir(databaseFolder);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet0() {
|
||||
|
||||
assertThat(activity, notNullValue());
|
||||
assertThat(getInstrumentation(), notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet1() {
|
||||
|
||||
KeyValueDataSource dataSource = createDataSource("test-state");
|
||||
try {
|
||||
byte[] key = Hex.decode("a1a2a3");
|
||||
byte[] val = Hex.decode("b1b2b3");
|
||||
|
||||
dataSource.put(key, val);
|
||||
byte[] val2 = dataSource.get(key);
|
||||
|
||||
assertThat(Hex.toHexString(val), is(Hex.toHexString(val2)));
|
||||
} finally {
|
||||
clear(dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet2() {
|
||||
|
||||
KeyValueDataSource states = createDataSource("test-state");
|
||||
KeyValueDataSource details = createDataSource("test-details");
|
||||
|
||||
try {
|
||||
byte[] key = Hex.decode("a1a2a3");
|
||||
byte[] val1 = Hex.decode("b1b2b3");
|
||||
byte[] val2 = Hex.decode("c1c2c3");
|
||||
|
||||
states.put(key, val1);
|
||||
details.put(key, val2);
|
||||
|
||||
byte[] res1 = states.get(key);
|
||||
byte[] res2 = details.get(key);
|
||||
|
||||
assertThat(Hex.toHexString(val1), is(Hex.toHexString(res1)));
|
||||
assertThat(Hex.toHexString(val2), is(Hex.toHexString(res2)));
|
||||
} finally {
|
||||
clear(states);
|
||||
clear(details);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
|
||||
private KeyValueDataSource createDataSource(String name) {
|
||||
|
||||
LevelDbDataSource result = new LevelDbDataSource();
|
||||
result.setContext(activity);
|
||||
result.setName(name);
|
||||
result.init();
|
||||
return result;
|
||||
}
|
||||
|
||||
private void clear(KeyValueDataSource dataSource) {
|
||||
|
||||
((LevelDbDataSource) dataSource).close();
|
||||
}
|
||||
|
||||
}
|
|
@ -2,15 +2,19 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.ethereum.android_app" >
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:name="org.ethereum.android_app.EthereumApplication"
|
||||
android:name=".EthereumApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name="org.ethereum.android_app.MainActivity"
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
@ -18,8 +22,10 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".TestActivity"
|
||||
android:label="@string/title_activity_test" >
|
||||
</activity>
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
</manifest>
|
||||
|
||||
</manifest>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -95,7 +95,9 @@ public class MainActivity extends ActionBarActivity {
|
|||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
ethereumManager.onDestroy();
|
||||
if (ethereumManager != null) {
|
||||
ethereumManager.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
// The definition of our task class
|
||||
|
@ -112,7 +114,14 @@ public class MainActivity extends ActionBarActivity {
|
|||
Log.v(TAG, "111");
|
||||
|
||||
Log.v(TAG, "222");
|
||||
long duration = ethereumManager.connect(SystemProperties.CONFIG.databaseDir() + File.separator + "poc-9-492k.dmp");
|
||||
ThreadGroup group = new ThreadGroup("threadGroup");
|
||||
new Thread(group, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long duration = ethereumManager.connect(SystemProperties.CONFIG.databaseDir() + File.separator + "poc-9-492k.dmp");
|
||||
}
|
||||
}, "EthereumConnect", 32768000).start();
|
||||
|
||||
//ConsoleFragment consoleeFrag = (ConsoleFragment)getSupportFragmentManager().findFragmentById(R.id.console);
|
||||
//consoleeFrag.updateDuration(duration);
|
||||
Log.v(TAG, "333");
|
||||
|
@ -158,7 +167,9 @@ public class MainActivity extends ActionBarActivity {
|
|||
protected String doInBackground(Context... params) {
|
||||
Log.v(TAG, "444");
|
||||
try {
|
||||
ethereumManager.startJsonRpc();
|
||||
if (ethereumManager != null) {
|
||||
ethereumManager.startJsonRpc();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
Log.v(TAG, "555");
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
|
||||
public class TestActivity extends ActionBarActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_test);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.menu_test, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (id == R.id.action_settings) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context="org.ethereum.android_app.TestActivity">
|
||||
|
||||
<TextView android:text="@string/hello_world" android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,7 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="org.ethereum.android_app.TestActivity">
|
||||
<item android:id="@+id/action_settings" android:title="@string/action_settings"
|
||||
android:orderInCategory="100" app:showAsAction="never" />
|
||||
</menu>
|
|
@ -1,3 +1,6 @@
|
|||
<resources>
|
||||
<dimen name="toolbar_elevation">4dp</dimen>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -6,5 +6,8 @@
|
|||
<string name="console_output">Console Output:</string>
|
||||
|
||||
<string name="ethereumj_tests">EthereumJ Tests</string>
|
||||
<string name="title_activity_test">TestActivity</string>
|
||||
|
||||
<string name="hello_world">Hello world!</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -22,8 +22,6 @@ import java.util.HashSet;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* @author Roman Mandeleil
|
||||
* @since 18.01.2015
|
||||
|
@ -34,7 +32,6 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
|||
|
||||
String name;
|
||||
private DB db;
|
||||
private Context context;
|
||||
|
||||
public LevelDbDataSource() {
|
||||
}
|
||||
|
@ -43,10 +40,6 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
public void setContext(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
package org.ethereum.android.datasource;
|
||||
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.datasource.KeyValueDataSource;
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.mapdb.DB;
|
||||
import org.mapdb.DBMaker;
|
||||
import org.mapdb.HTreeMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.ethereum.util.ByteUtil.wrap;
|
||||
|
||||
public class MapDBDataSource implements KeyValueDataSource {
|
||||
|
||||
private DB db;
|
||||
private HTreeMap<ByteArrayWrapper, byte[]> map;
|
||||
private String name;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
File dbLocation = new File(SystemProperties.CONFIG.databaseDir() + "/");
|
||||
if (!dbLocation.exists()) {
|
||||
dbLocation.mkdirs();
|
||||
}
|
||||
|
||||
db = DBMaker.newFileDB(new File(dbLocation, name))
|
||||
.asyncWriteEnable()
|
||||
.mmapFileEnableIfSupported()
|
||||
.compressionEnable()
|
||||
.cacheSize(512)
|
||||
.closeOnJvmShutdown()
|
||||
.make();
|
||||
|
||||
this.map = db.createHashMap(name).makeOrGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] get(byte[] key) {
|
||||
return map.get(wrap(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] put(byte[] key, byte[] value) {
|
||||
try {
|
||||
return map.put(wrap(key), value);
|
||||
} finally {
|
||||
db.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(byte[] key) {
|
||||
try {
|
||||
map.remove(key);
|
||||
} finally {
|
||||
db.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<byte[]> keys() {
|
||||
HashSet<byte[]> result = new HashSet<>();
|
||||
for (ByteArrayWrapper key : map.keySet()) {
|
||||
result.add(key.getData());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBatch(Map<byte[], byte[]> rows) {
|
||||
try {
|
||||
for (byte[] key : rows.keySet()) {
|
||||
map.put(wrap(key), rows.get(key));
|
||||
}
|
||||
} finally {
|
||||
db.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
db.close();
|
||||
}
|
||||
}
|
|
@ -83,9 +83,7 @@ public class EthereumModule {
|
|||
@Singleton
|
||||
Repository provideRepository() {
|
||||
LevelDbDataSource detailsDS = new LevelDbDataSource();
|
||||
detailsDS.setContext(context);
|
||||
LevelDbDataSource stateDS = new LevelDbDataSource();
|
||||
stateDS.setContext(context);
|
||||
return new RepositoryImpl(detailsDS, stateDS);
|
||||
}
|
||||
|
||||
|
|
|
@ -150,6 +150,7 @@ dependencies {
|
|||
compile "commons-dbcp:commons-dbcp:1.4"
|
||||
compile "redis.clients:jedis:2.6.0"
|
||||
compile "com.h2database:h2:1.4.187"
|
||||
compile "org.mapdb:mapdb:1.0.7"
|
||||
|
||||
compile "org.slf4j:slf4j-log4j12:${slf4jVersion}"
|
||||
compile "log4j:apache-log4j-extras:${log4jVersion}"
|
||||
|
|
|
@ -47,6 +47,8 @@ public class SystemProperties {
|
|||
private final static String DEFAULT_KEY_VALUE_DATA_SOURCE = "leveldb";
|
||||
private final static boolean DEFAULT_REDIS_ENABLED = true;
|
||||
private static final String DEFAULT_BLOCKS_LOADER = "";
|
||||
private static final int DEFAULT_FLUSH_BATCH_SIZE = 5_000;
|
||||
private static final boolean DEFAULT_FLUSH_IGNORE_CONSENSUS = false;
|
||||
|
||||
|
||||
/* Testing */
|
||||
|
@ -254,6 +256,19 @@ public class SystemProperties {
|
|||
private boolean boolProperty(String key, Boolean defaultValue) {
|
||||
return Boolean.parseBoolean(prop.getProperty(key, String.valueOf(defaultValue)));
|
||||
}
|
||||
|
||||
private int intProperty(String key, int defaultValue) {
|
||||
return Integer.parseInt(prop.getProperty(key, String.valueOf(defaultValue)));
|
||||
}
|
||||
|
||||
public int flushBatchSize() {
|
||||
return intProperty("flush.batch.size", DEFAULT_FLUSH_BATCH_SIZE);
|
||||
}
|
||||
|
||||
public boolean flushIgnoreConsensus() {
|
||||
return boolProperty("flush.ignore.consensus", DEFAULT_FLUSH_IGNORE_CONSENSUS);
|
||||
|
||||
}
|
||||
|
||||
public String vmTraceDir() {
|
||||
return prop.getProperty("vm.structured.dir", DEFAULT_VM_TRACE_DIR);
|
||||
|
|
|
@ -294,9 +294,7 @@ public class BlockchainImpl implements Blockchain {
|
|||
track.commit();
|
||||
storeBlock(block, receipts);
|
||||
|
||||
|
||||
if (adminInfo.isConsensus() &&
|
||||
block.getNumber() % 5_000 == 0) {
|
||||
if (needFlush(block)) {
|
||||
repository.flush();
|
||||
blockStore.flush();
|
||||
}
|
||||
|
@ -321,6 +319,13 @@ public class BlockchainImpl implements Blockchain {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean needFlush(Block block) {
|
||||
boolean isBatchReached = block.getNumber() % CONFIG.flushBatchSize() == 0;
|
||||
boolean isConsensus = CONFIG.flushIgnoreConsensus() || adminInfo.isConsensus();
|
||||
|
||||
return isConsensus && isBatchReached;
|
||||
}
|
||||
|
||||
private byte[] calcReceiptsTrie(List<TransactionReceipt> receipts){
|
||||
//TODO Fix Trie hash for receipts - doesnt match cpp
|
||||
Trie receiptsTrie = new TrieImpl(null);
|
||||
|
|
|
@ -179,9 +179,6 @@ public class Wallet {
|
|||
}
|
||||
|
||||
public void applyTransaction(Transaction transaction) {
|
||||
|
||||
transactionMap.put(new ByteArrayWrapper(transaction.getHash()), transaction);
|
||||
|
||||
byte[] senderAddress = transaction.getSender();
|
||||
Account sender = rows.get(Hex.toHexString(senderAddress));
|
||||
if (sender != null) {
|
||||
|
|
|
@ -2,8 +2,6 @@ package org.ethereum.datasource;
|
|||
|
||||
import org.ethereum.config.SystemProperties;
|
||||
|
||||
import org.fusesource.leveldbjni.JniDBFactory;
|
||||
import org.fusesource.leveldbjni.internal.JniDB;
|
||||
import org.iq80.leveldb.CompressionType;
|
||||
import org.iq80.leveldb.DB;
|
||||
import org.iq80.leveldb.DBIterator;
|
||||
|
@ -64,23 +62,7 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
|||
}
|
||||
|
||||
logger.debug("Initializing new or existing database: '{}'", name);
|
||||
|
||||
try {
|
||||
db = JniDBFactory.factory.open(fileLocation, options);
|
||||
} catch (Throwable e) {
|
||||
System.out.println("No native version of LevelDB found");
|
||||
}
|
||||
|
||||
String cpu = System.getProperty("sun.arch.data.model");
|
||||
String os = System.getProperty("os.name");
|
||||
|
||||
if (db instanceof JniDB)
|
||||
System.out.println("Native version of LevelDB loaded for: " + os + "." + cpu + "bit");
|
||||
else{
|
||||
System.out.println("Pure Java version of LevelDB loaded");
|
||||
db = Iq80DBFactory.factory.open(fileLocation, options);
|
||||
}
|
||||
|
||||
db = factory.open(fileLocation, options);
|
||||
|
||||
} catch (IOException ioe) {
|
||||
logger.error(ioe.getMessage(), ioe);
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package org.ethereum.datasource.mapdb;
|
||||
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.datasource.KeyValueDataSource;
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.mapdb.DB;
|
||||
import org.mapdb.DBMaker;
|
||||
import org.mapdb.HTreeMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.lang.System.getProperty;
|
||||
import static org.ethereum.util.ByteUtil.wrap;
|
||||
|
||||
public class MapDBDataSource implements KeyValueDataSource {
|
||||
|
||||
private DB db;
|
||||
private HTreeMap<ByteArrayWrapper, byte[]> map;
|
||||
private String name;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
File dbLocation = new File(getProperty("user.dir") + "/" + SystemProperties.CONFIG.databaseDir() + "/");
|
||||
if (!dbLocation.exists()) {
|
||||
dbLocation.mkdirs();
|
||||
}
|
||||
|
||||
db = DBMaker.newFileDB(new File(dbLocation, name))
|
||||
.asyncWriteEnable()
|
||||
.mmapFileEnableIfSupported()
|
||||
.compressionEnable()
|
||||
.cacheSize(512)
|
||||
.closeOnJvmShutdown()
|
||||
.make();
|
||||
|
||||
this.map = db.createHashMap(name).makeOrGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] get(byte[] key) {
|
||||
return map.get(wrap(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] put(byte[] key, byte[] value) {
|
||||
try {
|
||||
return map.put(wrap(key), value);
|
||||
} finally {
|
||||
db.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(byte[] key) {
|
||||
try {
|
||||
map.remove(key);
|
||||
} finally {
|
||||
db.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<byte[]> keys() {
|
||||
HashSet<byte[]> result = new HashSet<>();
|
||||
for (ByteArrayWrapper key : map.keySet()) {
|
||||
result.add(key.getData());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBatch(Map<byte[], byte[]> rows) {
|
||||
try {
|
||||
for (byte[] key : rows.keySet()) {
|
||||
map.put(wrap(key), rows.get(key));
|
||||
}
|
||||
} finally {
|
||||
db.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
db.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.ethereum.datasource.mapdb;
|
||||
|
||||
import org.ethereum.datasource.KeyValueDataSource;
|
||||
|
||||
public interface MapDBFactory {
|
||||
|
||||
KeyValueDataSource createDataSource();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.ethereum.datasource.mapdb;
|
||||
|
||||
import org.ethereum.datasource.KeyValueDataSource;
|
||||
|
||||
public class MapDBFactoryImpl implements MapDBFactory {
|
||||
|
||||
@Override
|
||||
public KeyValueDataSource createDataSource() {
|
||||
return new MapDBDataSource();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package org.ethereum.datasource.redis;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
|
||||
|
@ -74,7 +75,7 @@ public class RedisSet<T> extends RedisStorage<T> implements Set<T> {
|
|||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return removeAll(Arrays.asList(o));
|
||||
return (o == null) || removeAll(Arrays.asList(o));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -110,7 +111,7 @@ public class RedisSet<T> extends RedisStorage<T> implements Set<T> {
|
|||
|
||||
@Override
|
||||
public boolean removeAll(final Collection<?> c) {
|
||||
return pooledWithResult(new Function<Jedis, Boolean>() {
|
||||
return CollectionUtils.isEmpty(c) || pooledWithResult(new Function<Jedis, Boolean>() {
|
||||
@Override
|
||||
public Boolean apply(Jedis jedis) {
|
||||
return jedis.srem(getName(), serialize(c)) == c.size();
|
||||
|
|
|
@ -15,7 +15,7 @@ import static org.ethereum.util.Functional.*;
|
|||
|
||||
public abstract class RedisStorage<T> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger("db");
|
||||
protected static final Logger log = LoggerFactory.getLogger("redis");
|
||||
|
||||
private byte[] name;
|
||||
private final JedisPool pool;
|
||||
|
|
|
@ -4,13 +4,14 @@ import org.ethereum.util.FastByteComparisons;
|
|||
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Roman Mandeleil
|
||||
* @since 11.06.2014
|
||||
*/
|
||||
public class ByteArrayWrapper implements Comparable<ByteArrayWrapper> {
|
||||
public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>, Serializable {
|
||||
|
||||
private final byte[] data;
|
||||
private int hashCode = 0;
|
||||
|
|
|
@ -5,6 +5,7 @@ import org.ethereum.core.BlockchainImpl;
|
|||
import org.ethereum.core.Wallet;
|
||||
import org.ethereum.datasource.KeyValueDataSource;
|
||||
import org.ethereum.datasource.LevelDbDataSource;
|
||||
import org.ethereum.datasource.mapdb.MapDBDataSource;
|
||||
import org.ethereum.db.BlockStore;
|
||||
import org.ethereum.db.InMemoryBlockStore;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
|
@ -76,8 +77,8 @@ public class EthereumModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
Repository provideRepository() {
|
||||
LevelDbDataSource detailsDS = new LevelDbDataSource();
|
||||
LevelDbDataSource stateDS = new LevelDbDataSource();
|
||||
MapDBDataSource detailsDS = new MapDBDataSource();
|
||||
MapDBDataSource stateDS = new MapDBDataSource();
|
||||
return new RepositoryImpl(detailsDS, stateDS);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,20 +53,22 @@ public class Memory implements ProgramTraceListenerAware {
|
|||
return data;
|
||||
}
|
||||
|
||||
public void write(int address, byte[] data, int dataSize, boolean limited) {
|
||||
|
||||
public void write(int address, byte[] data, boolean limited) {
|
||||
if (data.length < dataSize)
|
||||
dataSize = data.length;
|
||||
|
||||
if (!limited)
|
||||
extend(address, data.length);
|
||||
extend(address, dataSize);
|
||||
|
||||
int chunkIndex = address / CHUNK_SIZE;
|
||||
int chunkOffset = address % CHUNK_SIZE;
|
||||
|
||||
int toCapture = 0;
|
||||
if (limited)
|
||||
toCapture = (address + data.length > softSize) ? softSize - address : data.length;
|
||||
toCapture = (address + dataSize > softSize) ? softSize - address : dataSize;
|
||||
else
|
||||
toCapture = data.length;
|
||||
toCapture = dataSize;
|
||||
|
||||
int start = 0;
|
||||
|
||||
|
@ -82,12 +84,12 @@ public class Memory implements ProgramTraceListenerAware {
|
|||
start += captured;
|
||||
}
|
||||
|
||||
if (traceListener != null) traceListener.onMemoryWrite(address, data);
|
||||
if (traceListener != null) traceListener.onMemoryWrite(address, data, dataSize);
|
||||
}
|
||||
|
||||
public void extendAndWrite(int address, int allocSize, byte[] data) {
|
||||
extend(address, allocSize);
|
||||
write(address, data, false);
|
||||
write(address, data, data.length, false);
|
||||
}
|
||||
|
||||
public void extend(int address, int size) {
|
||||
|
|
|
@ -215,15 +215,15 @@ public class Program {
|
|||
}
|
||||
|
||||
public void memorySave(DataWord addrB, DataWord value) {
|
||||
memory.write(addrB.intValue(), value.getData(), false);
|
||||
memory.write(addrB.intValue(), value.getData(), value.getData().length, false);
|
||||
}
|
||||
|
||||
public void memorySaveLimited(int addr, byte[] value) {
|
||||
memory.write(addr, value, true);
|
||||
public void memorySaveLimited(int addr, byte[] data, int dataSize) {
|
||||
memory.write(addr, data, dataSize, true);
|
||||
}
|
||||
|
||||
public void memorySave(int addr, byte[] value) {
|
||||
memory.write(addr, value, false);
|
||||
memory.write(addr, value, value.length, false);
|
||||
}
|
||||
|
||||
public void memoryExpand(DataWord outDataOffs, DataWord outDataSize) {
|
||||
|
@ -500,7 +500,9 @@ public class Program {
|
|||
if (result != null) {
|
||||
byte[] buffer = result.getHReturn();
|
||||
int offset = msg.getOutDataOffs().intValue();
|
||||
this.memorySaveLimited(offset, buffer);
|
||||
int size = msg.getOutDataSize().intValue();
|
||||
|
||||
this.memorySaveLimited(offset, buffer, size);
|
||||
}
|
||||
|
||||
// 4. THE FLAG OF SUCCESS IS ONE PUSHED INTO THE STACK
|
||||
|
@ -1023,7 +1025,7 @@ public class Program {
|
|||
* used mostly for testing reasons
|
||||
*/
|
||||
public void initMem(byte[] data) {
|
||||
this.memory.write(0, data, false);
|
||||
this.memory.write(0, data, data.length, false);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -113,10 +113,10 @@ public class OpActions {
|
|||
.addParam("delta", delta);
|
||||
}
|
||||
|
||||
public Action addMemoryWrite(int address, byte[] data) {
|
||||
public Action addMemoryWrite(int address, byte[] data, int size) {
|
||||
return addAction(memory, Action.Name.write)
|
||||
.addParam("address", address)
|
||||
.addParam("data", toHexString(data));
|
||||
.addParam("data", toHexString(data).substring(0, size));
|
||||
}
|
||||
|
||||
public Action addStoragePut(DataWord key, DataWord value) {
|
||||
|
|
|
@ -13,8 +13,8 @@ public class ProgramTraceListener {
|
|||
if (enabled) actions.addMemoryExtend(delta);
|
||||
}
|
||||
|
||||
public void onMemoryWrite(int address, byte[] data) {
|
||||
if (enabled) actions.addMemoryWrite(address, data);
|
||||
public void onMemoryWrite(int address, byte[] data, int size) {
|
||||
if (enabled) actions.addMemoryWrite(address, data, size);
|
||||
}
|
||||
|
||||
public void onStackPop() {
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -64,19 +64,19 @@ peer.discovery.workers = 3
|
|||
|
||||
# connection timeout for trying to
|
||||
# connect to a peer [seconds]
|
||||
peer.connection.timeout = 300
|
||||
peer.connection.timeout = 2
|
||||
|
||||
# the time we wait to the network
|
||||
# to approve the transaction, the
|
||||
# transaction got approved when
|
||||
# include into a transactions msg
|
||||
# retrieved from the peer [seconds]
|
||||
transaction.approve.timeout = 300
|
||||
transaction.approve.timeout = 15
|
||||
|
||||
# the parameter specifies how much
|
||||
# time we will wait for a message
|
||||
# to come before closing the channel
|
||||
peer.channel.read.timeout = 300
|
||||
peer.channel.read.timeout = 30
|
||||
|
||||
# default directory where we keep
|
||||
# basic Serpent samples relative
|
||||
|
@ -184,8 +184,8 @@ root.hash.start = -1
|
|||
# The protocols supported by peer
|
||||
peer.capabilities = eth, shh
|
||||
|
||||
# Key value data source values: [leveldb/redis]
|
||||
keyvalue.datasource = leveldb
|
||||
# Key value data source values: [leveldb/redis/mapdb]
|
||||
keyvalue.datasource = mapdb
|
||||
|
||||
# Redis cloud enabled flag.
|
||||
# Allows using RedisConnection for creating cloud based data structures.
|
||||
|
@ -200,3 +200,6 @@ blockchain.only=false
|
|||
# the net
|
||||
blocks.loader=
|
||||
#E:\\temp\\_poc-9-blocks\\poc-9-492k_.dmp
|
||||
|
||||
flush.batch.size=5000
|
||||
flush.ignore.consensus=false
|
|
@ -45,7 +45,7 @@ public class MemoryTest {
|
|||
Memory memoryBuffer = new Memory();
|
||||
byte[] data = {1, 1, 1, 1};
|
||||
|
||||
memoryBuffer.write(0, data, false);
|
||||
memoryBuffer.write(0, data, data.length, false);
|
||||
|
||||
assertTrue(1 == memoryBuffer.getChunks().size());
|
||||
|
||||
|
@ -65,7 +65,7 @@ public class MemoryTest {
|
|||
Memory memoryBuffer = new Memory();
|
||||
byte[] data = Hex.decode("0101010101010101010101010101010101010101010101010101010101010101");
|
||||
|
||||
memoryBuffer.write(0, data, false);
|
||||
memoryBuffer.write(0, data, data.length, false);
|
||||
|
||||
assertTrue(1 == memoryBuffer.getChunks().size());
|
||||
|
||||
|
@ -86,7 +86,7 @@ public class MemoryTest {
|
|||
Memory memoryBuffer = new Memory();
|
||||
byte[] data = Hex.decode("010101010101010101010101010101010101010101010101010101010101010101");
|
||||
|
||||
memoryBuffer.write(0, data, false);
|
||||
memoryBuffer.write(0, data, data.length, false);
|
||||
|
||||
assertTrue(1 == memoryBuffer.getChunks().size());
|
||||
|
||||
|
@ -109,7 +109,7 @@ public class MemoryTest {
|
|||
byte[] data = new byte[1024];
|
||||
Arrays.fill(data, (byte) 1);
|
||||
|
||||
memoryBuffer.write(0, data, false);
|
||||
memoryBuffer.write(0, data, data.length, false);
|
||||
|
||||
assertTrue(1 == memoryBuffer.getChunks().size());
|
||||
|
||||
|
@ -131,7 +131,7 @@ public class MemoryTest {
|
|||
byte[] data = new byte[1025];
|
||||
Arrays.fill(data, (byte) 1);
|
||||
|
||||
memoryBuffer.write(0, data, false);
|
||||
memoryBuffer.write(0, data, data.length, false);
|
||||
|
||||
assertTrue(2 == memoryBuffer.getChunks().size());
|
||||
|
||||
|
@ -160,8 +160,8 @@ public class MemoryTest {
|
|||
byte[] data2 = new byte[1024];
|
||||
Arrays.fill(data2, (byte) 2);
|
||||
|
||||
memoryBuffer.write(0, data1, false);
|
||||
memoryBuffer.write(1024, data2, false);
|
||||
memoryBuffer.write(0, data1, data1.length, false);
|
||||
memoryBuffer.write(1024, data2, data2.length, false);
|
||||
|
||||
assertTrue(2 == memoryBuffer.getChunks().size());
|
||||
|
||||
|
@ -196,9 +196,9 @@ public class MemoryTest {
|
|||
byte[] data3 = new byte[1];
|
||||
Arrays.fill(data3, (byte) 3);
|
||||
|
||||
memoryBuffer.write(0, data1, false);
|
||||
memoryBuffer.write(1024, data2, false);
|
||||
memoryBuffer.write(2048, data3, false);
|
||||
memoryBuffer.write(0, data1, data1.length, false);
|
||||
memoryBuffer.write(1024, data2, data2.length, false);
|
||||
memoryBuffer.write(2048, data3, data3.length, false);
|
||||
|
||||
assertTrue(3 == memoryBuffer.getChunks().size());
|
||||
|
||||
|
@ -295,8 +295,8 @@ public class MemoryTest {
|
|||
byte[] data2 = new byte[1024];
|
||||
Arrays.fill(data2, (byte) 2);
|
||||
|
||||
memoryBuffer.write(0, data1, false);
|
||||
memoryBuffer.write(1024, data2, false);
|
||||
memoryBuffer.write(0, data1, data1.length, false);
|
||||
memoryBuffer.write(1024, data2, data2.length, false);
|
||||
|
||||
assertTrue(memoryBuffer.getChunks().size() == 2);
|
||||
assertTrue(memoryBuffer.size() == 2048);
|
||||
|
@ -330,8 +330,8 @@ public class MemoryTest {
|
|||
byte[] data2 = new byte[32];
|
||||
Arrays.fill(data2, (byte) 2);
|
||||
|
||||
memoryBuffer.write(0, data1, false);
|
||||
memoryBuffer.write(32, data2, false);
|
||||
memoryBuffer.write(0, data1, data1.length, false);
|
||||
memoryBuffer.write(32, data2, data2.length, false);
|
||||
|
||||
byte[] data = memoryBuffer.read(0, 64);
|
||||
|
||||
|
@ -352,7 +352,7 @@ public class MemoryTest {
|
|||
byte[] data1 = new byte[32];
|
||||
Arrays.fill(data1, (byte) 1);
|
||||
|
||||
memoryBuffer.write(0, data1, false);
|
||||
memoryBuffer.write(0, data1, data1.length, false);
|
||||
assertTrue(32 == memoryBuffer.size());
|
||||
|
||||
byte[] data = memoryBuffer.read(0, 64);
|
||||
|
@ -377,8 +377,8 @@ public class MemoryTest {
|
|||
byte[] data2 = new byte[1024];
|
||||
Arrays.fill(data2, (byte) 2);
|
||||
|
||||
memoryBuffer.write(0, data1, false);
|
||||
memoryBuffer.write(1024, data2, false);
|
||||
memoryBuffer.write(0, data1, data1.length, false);
|
||||
memoryBuffer.write(1024, data2, data2.length, false);
|
||||
|
||||
byte[] data = memoryBuffer.read(0, 2048);
|
||||
|
||||
|
@ -403,8 +403,8 @@ public class MemoryTest {
|
|||
byte[] data2 = new byte[1024];
|
||||
Arrays.fill(data2, (byte) 2);
|
||||
|
||||
memoryBuffer.write(0, data1, false);
|
||||
memoryBuffer.write(1024, data2, false);
|
||||
memoryBuffer.write(0, data1, data1.length, false);
|
||||
memoryBuffer.write(1024, data2, data2.length, false);
|
||||
|
||||
byte[] data = memoryBuffer.read(0, 2049);
|
||||
|
||||
|
@ -430,12 +430,12 @@ public class MemoryTest {
|
|||
byte[] data1 = new byte[6272];
|
||||
Arrays.fill(data1, (byte) 1);
|
||||
|
||||
memoryBuffer.write(2720, data1, true);
|
||||
memoryBuffer.write(2720, data1, data1.length, true);
|
||||
|
||||
byte lastZero = memoryBuffer.readByte(2719);
|
||||
byte firstOne = memoryBuffer.readByte(2721);
|
||||
|
||||
assertTrue(memoryBuffer.internalSize() == 3072);
|
||||
assertTrue(memoryBuffer.size() == 3072);
|
||||
assertTrue(lastZero == 0);
|
||||
assertTrue(firstOne == 1);
|
||||
|
||||
|
@ -451,4 +451,66 @@ public class MemoryTest {
|
|||
assertTrue(zero == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void memoryWriteLimited_2(){
|
||||
|
||||
Memory memoryBuffer = new Memory();
|
||||
memoryBuffer.extend(0, 3072);
|
||||
|
||||
byte[] data1 = new byte[6272];
|
||||
Arrays.fill(data1, (byte) 1);
|
||||
|
||||
memoryBuffer.write(2720, data1, 300, true);
|
||||
|
||||
byte lastZero = memoryBuffer.readByte(2719);
|
||||
byte firstOne = memoryBuffer.readByte(2721);
|
||||
|
||||
assertTrue(memoryBuffer.size() == 3072);
|
||||
assertTrue(lastZero == 0);
|
||||
assertTrue(firstOne == 1);
|
||||
|
||||
byte[] data = memoryBuffer.read(2720, 352);
|
||||
|
||||
int ones = 0; int zero = 0;
|
||||
for (int i = 0; i < data.length; ++i){
|
||||
if (data[i] == 1) ++ones;
|
||||
if (data[i] == 0) ++zero;
|
||||
}
|
||||
|
||||
assertTrue(ones == 300);
|
||||
assertTrue(zero == 52);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void memoryWriteLimited_3(){
|
||||
|
||||
Memory memoryBuffer = new Memory();
|
||||
memoryBuffer.extend(0, 128);
|
||||
|
||||
byte[] data1 = new byte[20];
|
||||
Arrays.fill(data1, (byte) 1);
|
||||
|
||||
memoryBuffer.write(10, data1, 40, true);
|
||||
|
||||
byte lastZero = memoryBuffer.readByte(9);
|
||||
byte firstOne = memoryBuffer.readByte(10);
|
||||
|
||||
assertTrue(memoryBuffer.size() == 128);
|
||||
assertTrue(lastZero == 0);
|
||||
assertTrue(firstOne == 1);
|
||||
|
||||
byte[] data = memoryBuffer.read(10, 30);
|
||||
|
||||
int ones = 0; int zero = 0;
|
||||
for (int i = 0; i < data.length; ++i){
|
||||
if (data[i] == 1) ++ones;
|
||||
if (data[i] == 0) ++zero;
|
||||
}
|
||||
|
||||
assertTrue(ones == 20);
|
||||
assertTrue(zero == 10);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue