forked from I2P_Developers/i2p.i2p
* NetDB, DatabaseeStoreMessage:
- Convert everything from DataStructure to the
new DatabaseEntry superclass
- Optimizations made possible by DatabaseEntry
- Don't rescan netDb directory unless changed
This commit is contained in:
@@ -12,6 +12,7 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DatabaseEntry;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
@@ -28,59 +29,39 @@ import net.i2p.data.TunnelId;
|
||||
public class DatabaseStoreMessage extends I2NPMessageImpl {
|
||||
public final static int MESSAGE_TYPE = 1;
|
||||
private Hash _key;
|
||||
private int _type;
|
||||
private LeaseSet _leaseSet;
|
||||
private RouterInfo _info;
|
||||
private byte[] _leaseSetCache;
|
||||
private byte[] _routerInfoCache;
|
||||
private DatabaseEntry _dbEntry;
|
||||
private byte[] _byteCache;
|
||||
private long _replyToken;
|
||||
private TunnelId _replyTunnel;
|
||||
private Hash _replyGateway;
|
||||
|
||||
public final static int KEY_TYPE_ROUTERINFO = 0;
|
||||
public final static int KEY_TYPE_LEASESET = 1;
|
||||
|
||||
public DatabaseStoreMessage(I2PAppContext context) {
|
||||
super(context);
|
||||
setValueType(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the key in the network database being stored
|
||||
*
|
||||
*/
|
||||
public Hash getKey() { return _key; }
|
||||
public void setKey(Hash key) { _key = key; }
|
||||
|
||||
/**
|
||||
* Defines the router info value in the network database being stored
|
||||
*
|
||||
*/
|
||||
public RouterInfo getRouterInfo() { return _info; }
|
||||
public void setRouterInfo(RouterInfo routerInfo) {
|
||||
_info = routerInfo;
|
||||
if (_info != null)
|
||||
setValueType(KEY_TYPE_ROUTERINFO);
|
||||
public Hash getKey() {
|
||||
if (_key != null)
|
||||
return _key; // receive
|
||||
if (_dbEntry != null)
|
||||
return _dbEntry.getHash(); // create
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the lease set value in the network database being stored
|
||||
*
|
||||
* Defines the entry in the network database being stored
|
||||
*/
|
||||
public LeaseSet getLeaseSet() { return _leaseSet; }
|
||||
public void setLeaseSet(LeaseSet leaseSet) {
|
||||
_leaseSet = leaseSet;
|
||||
if (_leaseSet != null)
|
||||
setValueType(KEY_TYPE_LEASESET);
|
||||
}
|
||||
|
||||
public DatabaseEntry getEntry() { return _dbEntry; }
|
||||
|
||||
/**
|
||||
* Defines type of key being stored in the network database -
|
||||
* either KEY_TYPE_ROUTERINFO or KEY_TYPE_LEASESET
|
||||
*
|
||||
* This also sets the key
|
||||
*/
|
||||
public int getValueType() { return _type; }
|
||||
public void setValueType(int type) { _type = type; }
|
||||
public void setEntry(DatabaseEntry entry) {
|
||||
_dbEntry = entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a reply is desired, this token specifies the message ID that should
|
||||
@@ -90,6 +71,7 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
|
||||
* @return positive reply token ID, or 0 if no reply is necessary.
|
||||
*/
|
||||
public long getReplyToken() { return _replyToken; }
|
||||
|
||||
/**
|
||||
* Update the reply token.
|
||||
*
|
||||
@@ -113,13 +95,10 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
|
||||
if (type != MESSAGE_TYPE) throw new I2NPMessageException("Message type is incorrect for this message");
|
||||
int curIndex = offset;
|
||||
|
||||
//byte keyData[] = new byte[Hash.HASH_LENGTH];
|
||||
//System.arraycopy(data, curIndex, keyData, 0, Hash.HASH_LENGTH);
|
||||
_key = Hash.create(data, curIndex);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
//_key = new Hash(keyData);
|
||||
|
||||
_type = (int)DataHelper.fromLong(data, curIndex, 1);
|
||||
type = (int)DataHelper.fromLong(data, curIndex, 1);
|
||||
curIndex++;
|
||||
|
||||
_replyToken = DataHelper.fromLong(data, curIndex, 4);
|
||||
@@ -131,39 +110,38 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
|
||||
_replyTunnel = new TunnelId(tunnel);
|
||||
curIndex += 4;
|
||||
|
||||
//byte gw[] = new byte[Hash.HASH_LENGTH];
|
||||
//System.arraycopy(data, curIndex, gw, 0, Hash.HASH_LENGTH);
|
||||
_replyGateway = Hash.create(data, curIndex);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
//_replyGateway = new Hash(gw);
|
||||
} else {
|
||||
_replyTunnel = null;
|
||||
_replyGateway = null;
|
||||
}
|
||||
|
||||
if (_type == KEY_TYPE_LEASESET) {
|
||||
_leaseSet = new LeaseSet();
|
||||
if (type == DatabaseEntry.KEY_TYPE_LEASESET) {
|
||||
_dbEntry = new LeaseSet();
|
||||
try {
|
||||
_leaseSet.readBytes(new ByteArrayInputStream(data, curIndex, data.length-curIndex));
|
||||
_dbEntry.readBytes(new ByteArrayInputStream(data, curIndex, data.length-curIndex));
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Error reading the leaseSet", dfe);
|
||||
}
|
||||
} else if (_type == KEY_TYPE_ROUTERINFO) {
|
||||
_info = new RouterInfo();
|
||||
} else if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
|
||||
_dbEntry = new RouterInfo();
|
||||
int compressedSize = (int)DataHelper.fromLong(data, curIndex, 2);
|
||||
curIndex += 2;
|
||||
|
||||
try {
|
||||
byte decompressed[] = DataHelper.decompress(data, curIndex, compressedSize);
|
||||
_info.readBytes(new ByteArrayInputStream(decompressed));
|
||||
_dbEntry.readBytes(new ByteArrayInputStream(decompressed));
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Error reading the routerInfo", dfe);
|
||||
} catch (IOException ioe) {
|
||||
throw new I2NPMessageException("Compressed routerInfo was corrupt", ioe);
|
||||
}
|
||||
} else {
|
||||
throw new I2NPMessageException("Invalid type of key read from the structure - " + _type);
|
||||
throw new I2NPMessageException("Invalid type of key read from the structure - " + type);
|
||||
}
|
||||
//if (!key.equals(_dbEntry.getHash()))
|
||||
// throw new I2NPMessageException("Hash mismatch in DSM");
|
||||
}
|
||||
|
||||
|
||||
@@ -172,28 +150,28 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
|
||||
int len = Hash.HASH_LENGTH + 1 + 4; // key+type+replyToken
|
||||
if (_replyToken > 0)
|
||||
len += 4 + Hash.HASH_LENGTH; // replyTunnel+replyGateway
|
||||
if (_type == KEY_TYPE_LEASESET) {
|
||||
_leaseSetCache = _leaseSet.toByteArray();
|
||||
len += _leaseSetCache.length;
|
||||
} else if (_type == KEY_TYPE_ROUTERINFO) {
|
||||
byte uncompressed[] = _info.toByteArray();
|
||||
byte compressed[] = DataHelper.compress(uncompressed);
|
||||
_routerInfoCache = compressed;
|
||||
len += compressed.length + 2;
|
||||
if (_dbEntry.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
|
||||
_byteCache = _dbEntry.toByteArray();
|
||||
} else if (_dbEntry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
|
||||
byte uncompressed[] = _dbEntry.toByteArray();
|
||||
_byteCache = DataHelper.compress(uncompressed);
|
||||
len += 2;
|
||||
}
|
||||
len += _byteCache.length;
|
||||
return len;
|
||||
}
|
||||
|
||||
/** write the message body to the output array, starting at the given index */
|
||||
protected int writeMessageBody(byte out[], int curIndex) throws I2NPMessageException {
|
||||
if (_key == null) throw new I2NPMessageException("Invalid key");
|
||||
if ( (_type != KEY_TYPE_LEASESET) && (_type != KEY_TYPE_ROUTERINFO) ) throw new I2NPMessageException("Invalid key type");
|
||||
if ( (_type == KEY_TYPE_LEASESET) && (_leaseSet == null) ) throw new I2NPMessageException("Missing lease set");
|
||||
if ( (_type == KEY_TYPE_ROUTERINFO) && (_info == null) ) throw new I2NPMessageException("Missing router info");
|
||||
if (_dbEntry == null) throw new I2NPMessageException("Missing entry");
|
||||
int type = _dbEntry.getType();
|
||||
if (type != DatabaseEntry.KEY_TYPE_LEASESET && type != DatabaseEntry.KEY_TYPE_ROUTERINFO)
|
||||
throw new I2NPMessageException("Invalid key type");
|
||||
|
||||
System.arraycopy(_key.getData(), 0, out, curIndex, Hash.HASH_LENGTH);
|
||||
// Use the hash of the DatabaseEntry
|
||||
System.arraycopy(getKey().getData(), 0, out, curIndex, Hash.HASH_LENGTH);
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
byte type[] = DataHelper.toLong(1, _type);
|
||||
out[curIndex++] = type[0];
|
||||
out[curIndex++] = (byte) type;
|
||||
byte tok[] = DataHelper.toLong(4, _replyToken);
|
||||
System.arraycopy(tok, 0, out, curIndex, 4);
|
||||
curIndex += 4;
|
||||
@@ -209,17 +187,14 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
}
|
||||
|
||||
if (_type == KEY_TYPE_LEASESET) {
|
||||
// initialized in calculateWrittenLength
|
||||
System.arraycopy(_leaseSetCache, 0, out, curIndex, _leaseSetCache.length);
|
||||
curIndex += _leaseSetCache.length;
|
||||
} else if (_type == KEY_TYPE_ROUTERINFO) {
|
||||
byte len[] = DataHelper.toLong(2, _routerInfoCache.length);
|
||||
// _byteCache initialized in calculateWrittenLength
|
||||
if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
|
||||
byte len[] = DataHelper.toLong(2, _byteCache.length);
|
||||
out[curIndex++] = len[0];
|
||||
out[curIndex++] = len[1];
|
||||
System.arraycopy(_routerInfoCache, 0, out, curIndex, _routerInfoCache.length);
|
||||
curIndex += _routerInfoCache.length;
|
||||
}
|
||||
System.arraycopy(_byteCache, 0, out, curIndex, _byteCache.length);
|
||||
curIndex += _byteCache.length;
|
||||
return curIndex;
|
||||
}
|
||||
|
||||
@@ -228,9 +203,7 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return DataHelper.hashCode(getKey()) +
|
||||
DataHelper.hashCode(getLeaseSet()) +
|
||||
DataHelper.hashCode(getRouterInfo()) +
|
||||
getValueType() +
|
||||
DataHelper.hashCode(_dbEntry) +
|
||||
(int)getReplyToken() +
|
||||
DataHelper.hashCode(getReplyTunnel()) +
|
||||
DataHelper.hashCode(getReplyGateway());
|
||||
@@ -241,9 +214,7 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
|
||||
if ( (object != null) && (object instanceof DatabaseStoreMessage) ) {
|
||||
DatabaseStoreMessage msg = (DatabaseStoreMessage)object;
|
||||
return DataHelper.eq(getKey(),msg.getKey()) &&
|
||||
DataHelper.eq(getLeaseSet(),msg.getLeaseSet()) &&
|
||||
DataHelper.eq(getRouterInfo(),msg.getRouterInfo()) &&
|
||||
_type == msg.getValueType() &&
|
||||
DataHelper.eq(_dbEntry,msg.getEntry()) &&
|
||||
getReplyToken() == msg.getReplyToken() &&
|
||||
DataHelper.eq(getReplyTunnel(), msg.getReplyTunnel()) &&
|
||||
DataHelper.eq(getReplyGateway(), msg.getReplyGateway());
|
||||
@@ -259,9 +230,7 @@ public class DatabaseStoreMessage extends I2NPMessageImpl {
|
||||
buf.append("\n\tExpiration: ").append(getMessageExpiration());
|
||||
buf.append("\n\tUnique ID: ").append(getUniqueId());
|
||||
buf.append("\n\tKey: ").append(getKey());
|
||||
buf.append("\n\tValue Type: ").append(getValueType());
|
||||
buf.append("\n\tRouter Info: ").append(getRouterInfo());
|
||||
buf.append("\n\tLease Set: ").append(getLeaseSet());
|
||||
buf.append("\n\tEntry: ").append(_dbEntry);
|
||||
buf.append("\n\tReply token: ").append(getReplyToken());
|
||||
buf.append("\n\tReply tunnel: ").append(getReplyTunnel());
|
||||
buf.append("\n\tReply gateway: ").append(getReplyGateway());
|
||||
|
||||
Reference in New Issue
Block a user