mirror of
https://github.com/ChronosX88/Influence-P2P.git
synced 2024-11-22 07:12:19 +00:00
Implemented custom storage for peer (standard impl isn't working on Android, so custom impl was build on top of MVStore), added JBoss Serialization lib. Also added basic peer initialization (non architectured yet)
This commit is contained in:
parent
1ccc891503
commit
cd0300eea0
@ -3,6 +3,9 @@
|
|||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
|
<compositeConfiguration>
|
||||||
|
<compositeBuild compositeDefinitionSource="SCRIPT" />
|
||||||
|
</compositeConfiguration>
|
||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||||
<option name="myNullables">
|
<option name="myNullables">
|
||||||
<value>
|
<value>
|
||||||
<list size="7">
|
<list size="10">
|
||||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||||
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
||||||
@ -13,18 +13,24 @@
|
|||||||
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||||
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
|
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
|
||||||
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
|
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
|
||||||
|
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
|
||||||
|
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
|
||||||
|
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
|
||||||
</list>
|
</list>
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
<option name="myNotNulls">
|
<option name="myNotNulls">
|
||||||
<value>
|
<value>
|
||||||
<list size="6">
|
<list size="9">
|
||||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||||
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
|
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
|
||||||
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
|
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
|
||||||
|
<item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
|
||||||
|
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
|
||||||
|
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
|
||||||
</list>
|
</list>
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
|
@ -19,6 +19,13 @@ android {
|
|||||||
packagingOptions {
|
packagingOptions {
|
||||||
exclude 'META-INF/INDEX.LIST'
|
exclude 'META-INF/INDEX.LIST'
|
||||||
exclude 'META-INF/io.netty.versions.properties'
|
exclude 'META-INF/io.netty.versions.properties'
|
||||||
|
exclude 'LICENSE-EPL-1.0.txt'
|
||||||
|
exclude 'LICENSE-EDL-1.0.txt'
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,5 +36,13 @@ dependencies {
|
|||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
|
||||||
implementation "androidx.room:room-runtime:$room_version"
|
implementation "androidx.room:room-runtime:$room_version"
|
||||||
annotationProcessor "androidx.room:room-compiler:$room_version"
|
annotationProcessor "androidx.room:room-compiler:$room_version"
|
||||||
implementation 'net.tomp2p:tomp2p-all:5.0-Beta8'
|
implementation('net.tomp2p:tomp2p-all:5.0-Beta8') {
|
||||||
|
exclude group: 'org.mapdb', module: 'mapdb'
|
||||||
|
}
|
||||||
|
implementation 'io.paperdb:paperdb:2.6'
|
||||||
|
implementation 'org.slf4j:slf4j-log4j12:+'
|
||||||
|
implementation 'com.github.nolia:Noodle:0.5'
|
||||||
|
implementation group: 'com.h2database', name: 'h2-mvstore', version: '1.4.197'
|
||||||
|
//implementation 'org.jboss:jdk-misc:2.Final'
|
||||||
|
//implementation group: 'jboss', name: 'jboss-serialization', version: '4.2.2.GA'
|
||||||
}
|
}
|
||||||
|
BIN
app/libs/jboss-serialization.jar
Normal file
BIN
app/libs/jboss-serialization.jar
Normal file
Binary file not shown.
BIN
app/libs/trove.jar
Normal file
BIN
app/libs/trove.jar
Normal file
Binary file not shown.
@ -10,7 +10,7 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
android:name=".App">
|
android:name=".AppHelper">
|
||||||
<activity android:name=".MainActivity">
|
<activity android:name=".MainActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
@ -7,7 +7,7 @@ import android.content.Context;
|
|||||||
* Extended Application class which designed for getting Context from anywhere in the application.
|
* Extended Application class which designed for getting Context from anywhere in the application.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class App extends Application {
|
public class AppHelper extends Application {
|
||||||
private static Application instance;
|
private static Application instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -4,34 +4,20 @@ import android.content.SharedPreferences;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import net.tomp2p.connection.RSASignatureFactory;
|
|
||||||
import net.tomp2p.dht.PeerBuilderDHT;
|
import net.tomp2p.dht.PeerBuilderDHT;
|
||||||
import net.tomp2p.dht.PeerDHT;
|
import net.tomp2p.dht.PeerDHT;
|
||||||
import net.tomp2p.dht.Storage;
|
|
||||||
import net.tomp2p.dht.StorageLayer;
|
|
||||||
import net.tomp2p.dht.StorageMemory;
|
|
||||||
import net.tomp2p.futures.FutureBootstrap;
|
import net.tomp2p.futures.FutureBootstrap;
|
||||||
import net.tomp2p.futures.FutureDiscover;
|
import net.tomp2p.futures.FutureDiscover;
|
||||||
import net.tomp2p.p2p.PeerBuilder;
|
import net.tomp2p.p2p.PeerBuilder;
|
||||||
import net.tomp2p.peers.Number160;
|
import net.tomp2p.peers.Number160;
|
||||||
import net.tomp2p.peers.Number320;
|
|
||||||
import net.tomp2p.peers.Number480;
|
|
||||||
import net.tomp2p.peers.Number640;
|
|
||||||
import net.tomp2p.storage.Data;
|
|
||||||
import net.tomp2p.storage.StorageDisk;
|
|
||||||
|
|
||||||
import org.mapdb.DBMaker;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.NavigableMap;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import io.github.chronosx88.influence.helpers.StorageMVStore;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@ -42,18 +28,20 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
org.apache.log4j.BasicConfigurator.configure();
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
preferences = getPreferences(MODE_PRIVATE);
|
preferences = getSharedPreferences("main_config", MODE_PRIVATE);
|
||||||
|
|
||||||
if(checkFirstRun()) {
|
if(checkFirstRun()) {
|
||||||
SharedPreferences.Editor editor = preferences.edit();
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
editor.putString("peerID", UUID.randomUUID().toString());
|
String uuid = UUID.randomUUID().toString();
|
||||||
|
editor.putString("peerID", uuid);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
} else {
|
|
||||||
peerID = Number160.createHash(preferences.getString("peerID", "0"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
peerID = Number160.createHash(preferences.getString("peerID", "0"));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
peerDHT = new PeerBuilderDHT(
|
peerDHT = new PeerBuilderDHT(
|
||||||
new PeerBuilder(peerID)
|
new PeerBuilder(peerID)
|
||||||
@ -61,17 +49,17 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
.behindFirewall(true)
|
.behindFirewall(true)
|
||||||
.start()
|
.start()
|
||||||
)
|
)
|
||||||
.storage(new StorageDisk(peerID, getFilesDir(), new RSASignatureFactory()))
|
.storage(new StorageMVStore(peerID, getFilesDir()))
|
||||||
.start();
|
.start();
|
||||||
InetAddress address = Inet4Address.getByName("192.168.0.82");
|
InetAddress address = Inet4Address.getByName("*IP*");
|
||||||
FutureDiscover futureDiscover = peerDHT.peer().discover().inetAddress( address ).ports( 7243 ).start();
|
FutureDiscover futureDiscover = peerDHT.peer().discover().inetAddress( address ).ports( 7243 ).start();
|
||||||
futureDiscover.awaitUninterruptibly();
|
futureDiscover.awaitUninterruptibly();
|
||||||
FutureBootstrap futureBootstrap = peerDHT.peer().bootstrap().inetAddress( address ).ports( 7243 ).start();
|
FutureBootstrap futureBootstrap = peerDHT.peer().bootstrap().inetAddress( address ).ports( 7243 ).start();
|
||||||
futureBootstrap.awaitUninterruptibly();
|
futureBootstrap.awaitUninterruptibly();
|
||||||
|
Log.d("", futureBootstrap.failedReason());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkFirstRun() {
|
public boolean checkFirstRun() {
|
||||||
@ -85,9 +73,8 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onDestroy() {
|
||||||
super.onStop();
|
super.onDestroy();
|
||||||
Log.wtf("MainActivity", "onStop");
|
|
||||||
peerDHT.shutdown();
|
peerDHT.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package io.github.chronosx88.influence.helpers;
|
||||||
|
|
||||||
|
public class JVMShutdownHook extends Thread {
|
||||||
|
StorageMVStore storage;
|
||||||
|
|
||||||
|
public JVMShutdownHook(StorageMVStore storage) {
|
||||||
|
this.storage = storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
super.run();
|
||||||
|
storage.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package io.github.chronosx88.influence.helpers;
|
||||||
|
|
||||||
|
import org.jboss.serial.io.JBossObjectInputStream;
|
||||||
|
import org.jboss.serial.io.JBossObjectOutputStream;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class Serializer {
|
||||||
|
public static <T> String serializeObject(T t) {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
JBossObjectOutputStream out = new JBossObjectOutputStream(outputStream);
|
||||||
|
out.writeObject(t);
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return outputStream.toString("UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T deserializeObject(String str) {
|
||||||
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
|
||||||
|
T obj = null;
|
||||||
|
try {
|
||||||
|
JBossObjectInputStream in = new JBossObjectInputStream(inputStream);
|
||||||
|
obj = (T) in.readObject();
|
||||||
|
in.close();
|
||||||
|
inputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,295 @@
|
|||||||
|
package io.github.chronosx88.influence.helpers;
|
||||||
|
|
||||||
|
import net.tomp2p.dht.Storage;
|
||||||
|
import net.tomp2p.peers.Number160;
|
||||||
|
import net.tomp2p.peers.Number320;
|
||||||
|
import net.tomp2p.peers.Number480;
|
||||||
|
import net.tomp2p.peers.Number640;
|
||||||
|
import net.tomp2p.storage.Data;
|
||||||
|
|
||||||
|
import org.h2.mvstore.MVMap;
|
||||||
|
import org.h2.mvstore.MVStore;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class StorageMVStore implements Storage {
|
||||||
|
private MVStore db;
|
||||||
|
|
||||||
|
// Core
|
||||||
|
final private MVMap<String, String> dataMap; // <Number 640, Data>
|
||||||
|
|
||||||
|
// Maintenance
|
||||||
|
final private MVMap<String, String> timeoutMap; // <Number640, Long>
|
||||||
|
final private MVMap<String, String> timeoutMapRev; // <Long, Set<Number640>>
|
||||||
|
|
||||||
|
// Protection
|
||||||
|
final private MVMap<String, String> protectedDomainMap; // <Number320, PublicKey>
|
||||||
|
final private MVMap<String, String> protectedEntryMap; // <Number480, PublicKey>
|
||||||
|
|
||||||
|
// Responsibility
|
||||||
|
final private MVMap<String, String> responsibilityMap; // <Number160, Number160>
|
||||||
|
final private MVMap<String, String> responsibilityMapRev; // <Number160, Set<Number160>>
|
||||||
|
|
||||||
|
final private int storageCheckIntervalMillis;
|
||||||
|
|
||||||
|
public StorageMVStore(Number160 peerID, File path) {
|
||||||
|
db = new MVStore.Builder()
|
||||||
|
.fileName(path.getAbsolutePath() + "/coreDB.db")
|
||||||
|
.open();
|
||||||
|
dataMap = db.openMap("dataMap_" + peerID.toString());
|
||||||
|
timeoutMap = db.openMap("timeoutMap_" + peerID.toString());
|
||||||
|
timeoutMapRev = db.openMap("timeoutMapRev_" + peerID.toString());
|
||||||
|
protectedDomainMap = db.openMap("protectedDomainMap_" + peerID.toString());
|
||||||
|
protectedEntryMap = db.openMap("protectedEntryMap_" + peerID.toString());
|
||||||
|
responsibilityMap = db.openMap("responsibilityMap_" + peerID.toString());
|
||||||
|
responsibilityMapRev = db.openMap("responsibilityMapRev_ " + peerID.toString());
|
||||||
|
storageCheckIntervalMillis = 60 * 1000;
|
||||||
|
Runtime.getRuntime().addShutdownHook(new JVMShutdownHook(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Data put(Number640 key, Data value) {
|
||||||
|
Data oldData = Serializer.deserializeObject(dataMap.put(Serializer.serializeObject(key), Serializer.serializeObject(value)));
|
||||||
|
db.commit();
|
||||||
|
return oldData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Data get(Number640 key) {
|
||||||
|
return Serializer.deserializeObject(dataMap.get(Serializer.serializeObject(key)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Number640 key) {
|
||||||
|
return dataMap.containsKey(Serializer.serializeObject(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int contains(Number640 from, Number640 to) {
|
||||||
|
TreeMap<Number640, Data> tmp = new TreeMap<>();
|
||||||
|
for (Map.Entry<String, String> entry: dataMap.entrySet()) {
|
||||||
|
tmp.put(Serializer.deserializeObject(entry.getKey()), Serializer.deserializeObject(entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmp.subMap(from, true, to, true).size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Data remove(Number640 key, boolean returnData) {
|
||||||
|
Data retVal = Serializer.deserializeObject(dataMap.remove(Serializer.serializeObject(key)));
|
||||||
|
db.commit();
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavigableMap<Number640, Data> remove(Number640 from, Number640 to) {
|
||||||
|
TreeMap<Number640, Data> tmp = new TreeMap<>();
|
||||||
|
for (Map.Entry<String, String> entry: dataMap.entrySet()) {
|
||||||
|
tmp.put(Serializer.deserializeObject(entry.getKey()), Serializer.deserializeObject(entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigableMap<Number640, Data> tmpSubMap = tmp.subMap(from, true, to, true);
|
||||||
|
for (Map.Entry<Number640, Data> entry : tmpSubMap.entrySet()) {
|
||||||
|
dataMap.remove(Serializer.serializeObject(entry.getKey()));
|
||||||
|
}
|
||||||
|
db.commit();
|
||||||
|
|
||||||
|
return tmpSubMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavigableMap<Number640, Data> subMap(Number640 from, Number640 to, int limit, boolean ascending) {
|
||||||
|
TreeMap<Number640, Data> tmpDataMap = new TreeMap<>();
|
||||||
|
for (Map.Entry<String, String> entry: dataMap.entrySet()) {
|
||||||
|
tmpDataMap.put(Serializer.deserializeObject(entry.getKey()), Serializer.deserializeObject(entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigableMap<Number640, Data> tmp = tmpDataMap.subMap(from, true, to, true);
|
||||||
|
final NavigableMap<Number640, Data> retVal = new TreeMap<>();
|
||||||
|
|
||||||
|
if (limit < 0) {
|
||||||
|
for(final Map.Entry<Number640, Data> entry:(ascending ? tmp : tmp.descendingMap()).entrySet()) {
|
||||||
|
retVal.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
limit = Math.min(limit, tmp.size());
|
||||||
|
Iterator<Map.Entry<Number640, Data>> iterator = ascending ? tmp.entrySet().iterator() : tmp
|
||||||
|
.descendingMap().entrySet().iterator();
|
||||||
|
for (int i = 0; iterator.hasNext() && i < limit; i++) {
|
||||||
|
Map.Entry<Number640, Data> entry = iterator.next();
|
||||||
|
retVal.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavigableMap<Number640, Data> map() {
|
||||||
|
final NavigableMap<Number640, Data> retVal = new TreeMap<>();
|
||||||
|
for(final Map.Entry<String, String> entry:dataMap.entrySet()) {
|
||||||
|
retVal.put(Serializer.deserializeObject(entry.getKey()), Serializer.deserializeObject(entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTimeout(Number640 key, long expiration) {
|
||||||
|
Long oldExpiration = Serializer.deserializeObject(timeoutMap.put(Serializer.serializeObject(key), Serializer.serializeObject(expiration)));
|
||||||
|
putIfAbsent2(expiration, key);
|
||||||
|
if (oldExpiration == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
removeRevTimeout(key, oldExpiration);
|
||||||
|
db.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putIfAbsent2(long expiration, Number640 key) {
|
||||||
|
Set<Number640> timeouts = Serializer.deserializeObject(timeoutMapRev.get(Serializer.serializeObject(expiration)));
|
||||||
|
if(timeouts == null) {
|
||||||
|
timeouts = Collections.newSetFromMap(new ConcurrentHashMap<Number640, Boolean>());
|
||||||
|
}
|
||||||
|
timeouts.add(key);
|
||||||
|
timeoutMapRev.put(Serializer.serializeObject(expiration), Serializer.serializeObject(timeouts));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeRevTimeout(Number640 key, Long expiration) {
|
||||||
|
Set<Number640> tmp = Serializer.deserializeObject(timeoutMapRev.get(Serializer.serializeObject(expiration)));
|
||||||
|
if (tmp != null) {
|
||||||
|
tmp.remove(key);
|
||||||
|
if (tmp.isEmpty()) {
|
||||||
|
timeoutMapRev.remove(expiration);
|
||||||
|
} else {
|
||||||
|
timeoutMapRev.put(Serializer.serializeObject(expiration), Serializer.serializeObject(tmp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeTimeout(Number640 key) {
|
||||||
|
Long expiration = Serializer.deserializeObject(timeoutMap.remove(Serializer.serializeObject(key)));
|
||||||
|
if (expiration == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
removeRevTimeout(key, expiration);
|
||||||
|
db.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Number640> subMapTimeout(long to) {
|
||||||
|
TreeMap<Long, Set<Number640>> tmpTimeoutMapRev = new TreeMap<>();
|
||||||
|
for (Map.Entry<String, String> entry: timeoutMapRev.entrySet()) {
|
||||||
|
tmpTimeoutMapRev.put(Serializer.deserializeObject(entry.getKey()), Serializer.deserializeObject(entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SortedMap<Long, Set<Number640>> tmp = tmpTimeoutMapRev.subMap(0L, to);
|
||||||
|
Collection<Number640> toRemove = new ArrayList<>();
|
||||||
|
for (Set<Number640> set : tmp.values()) {
|
||||||
|
toRemove.addAll(set);
|
||||||
|
}
|
||||||
|
return toRemove;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int storageCheckIntervalMillis() {
|
||||||
|
return this.storageCheckIntervalMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean protectDomain(Number320 key, PublicKey publicKey) {
|
||||||
|
protectedDomainMap.put(Serializer.serializeObject(key), Serializer.serializeObject(publicKey));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDomainProtectedByOthers(Number320 key, PublicKey publicKey) {
|
||||||
|
PublicKey other = Serializer.deserializeObject(protectedDomainMap.get(Serializer.serializeObject(key)));
|
||||||
|
if (other == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !other.equals(publicKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean protectEntry(Number480 key, PublicKey publicKey) {
|
||||||
|
protectedEntryMap.put(Serializer.serializeObject(key), Serializer.serializeObject(publicKey));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEntryProtectedByOthers(Number480 key, PublicKey publicKey) {
|
||||||
|
PublicKey other = Serializer.deserializeObject(protectedEntryMap.get(Serializer.serializeObject(key)));
|
||||||
|
if (other == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !other.equals(publicKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Number160 findPeerIDsForResponsibleContent(Number160 locationKey) {
|
||||||
|
return Serializer.deserializeObject(responsibilityMap.get(Serializer.serializeObject(locationKey)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Number160> findContentForResponsiblePeerID(Number160 peerID) {
|
||||||
|
return Serializer.deserializeObject(responsibilityMapRev.get(Serializer.serializeObject(peerID)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateResponsibilities(Number160 locationKey, Number160 peerId) {
|
||||||
|
final Number160 oldPeerID = Serializer.deserializeObject(responsibilityMap.put(Serializer.serializeObject(locationKey), Serializer.serializeObject(peerId)));
|
||||||
|
final boolean hasChanged;
|
||||||
|
if(oldPeerID != null) {
|
||||||
|
if(oldPeerID.equals(peerId)) {
|
||||||
|
hasChanged = false;
|
||||||
|
} else {
|
||||||
|
removeRevResponsibility(oldPeerID, locationKey);
|
||||||
|
hasChanged = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasChanged = true;
|
||||||
|
}
|
||||||
|
Set<Number160> contentIDs = Serializer.deserializeObject(responsibilityMapRev.get(Serializer.serializeObject(peerId)));
|
||||||
|
if(contentIDs == null) {
|
||||||
|
contentIDs = new HashSet<Number160>();
|
||||||
|
}
|
||||||
|
contentIDs.add(locationKey);
|
||||||
|
responsibilityMapRev.put(Serializer.serializeObject(peerId), Serializer.serializeObject(contentIDs));
|
||||||
|
db.commit();
|
||||||
|
return hasChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeResponsibility(Number160 locationKey) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeRevResponsibility(Number160 peerId, Number160 locationKey) {
|
||||||
|
Set<Number160> contentIDs = Serializer.deserializeObject(responsibilityMapRev.get(Serializer.serializeObject(peerId)));
|
||||||
|
if (contentIDs != null) {
|
||||||
|
contentIDs.remove(locationKey);
|
||||||
|
if (contentIDs.isEmpty()) {
|
||||||
|
responsibilityMapRev.remove(peerId);
|
||||||
|
} else {
|
||||||
|
responsibilityMapRev.put(Serializer.serializeObject(peerId), Serializer.serializeObject(contentIDs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,8 @@ allprojects {
|
|||||||
maven {
|
maven {
|
||||||
url "http://tomp2p.net/dev/mvn/"
|
url "http://tomp2p.net/dev/mvn/"
|
||||||
}
|
}
|
||||||
|
mavenCentral()
|
||||||
|
maven { url 'https://jitpack.io' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,5 +14,6 @@ org.gradle.jvmargs=-Xmx1536m
|
|||||||
|
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
android.enableD8=true
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user