📄 chordid.java
字号:
package planet.chord;
import java.math.BigInteger;
import java.util.Random;
import planet.commonapi.Id;
import planet.util.Properties;
import planet.util.Utilities;
/**
* Spedific Chord Id implementation.
* @author <a href="mailto: jordi.pujol@estudiants.urv.es">Jordi Pujol</a>
* 25/02/2005
*/
public class ChordId extends Id implements java.io.Serializable {
/* ******************* CHORD SPECIFIC CONSTANTS **************/
/**
* Chord specific constant: Maximum number of bits for any Id.
*/
public static final int MAX_BITS = 160;
/**
* Chord specific constant: Number of bits saved at any array position.
*/
public static final int MIN_BITS = 32;
/**
* Chord specific constant: Maximum value of internal value of Id.
*/
//public static final int[] MAX_CHORD = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};
/**
* Chord specific constant: The value of one (1) of internal value of Id.
*/
public static final int[] ONE_CHORD = {0x1, 0, 0, 0, 0};
/**
* Chord specific constant: The value of two (2) of internal value of Id.
*/
public static final int[] TWO_CHORD = {0x2, 0, 0, 0, 0};
/**
* Chord specific constant: Each array position contains a maximum
* representation of MODULE bits.
*/
protected static final int MODULE = MIN_BITS;
/**
* Chord specific constant: Maximum size of array that contains entire identification.
*/
protected static final int MAX_ARRAY_SIZE = MAX_BITS/MODULE;
/* END ******************* CHORD SPECIFIC CONSTANTS **************/
/* *********** STATIC ATTRIBUTES FOR getMaximum() METHOD ********/
/** Sets the number of bits used in last building of MAX. */
protected static int bitsKey;
/** Maximum value for the ChordId implementation. */
protected static Id MAX;
/* END *********** STATIC ATTRIBUTES FOR getMaximum() METHOD ********/
/**
* number of elements in the array
*/
private int arrayElems = ((ChordProperties)Properties.overlayPropertiesInstance).bitsPerKey / 32;
/**
* The number of bits per key as is shown in the current configuration.
*/
protected int bitsPerKey = ((ChordProperties)Properties.overlayPropertiesInstance).bitsPerKey;
/**
* the id itself.
*/
private int[] Id;
/** Auxiliar id. */
private ChordId offsetId = null;
/**
* Generates an Id initialized to zero.
* It is not required for the framework.
*/
public ChordId() {
Id = new int[arrayElems];
for (int i = 0; i < arrayElems; i++)
Id[i] = 0;
}
/**
* Capture the MSB (More Significative Bits) of the identification,
* in fragments of MODULE bits (32 bits). The MSB remain the MSB
* at new identification and are discarded the LSB (Less Significative
* Bits).
* @param dataForId Array with any size, with fragments of representation
* of MODULE bits.
*/
private void translate(int[] dataForId) {
int dataLength = this.getLastIndex(dataForId) + 1;
if (arrayElems == dataLength) {
for (int i = 0; i < arrayElems; i++) {
Id[i] = dataForId[i];
}
} else if (arrayElems < dataLength) {
int length = dataLength-1;
int arrayLength = arrayElems-1;
for (int i = 0; i < arrayElems; i++) {
Id[arrayLength-i] = dataForId[length-i];
}
} else { // ArrayElems > DataLength
int i = 0;
// Capture first elements from dataForId
for (i=0; i<dataLength; i++) {
Id[i] = dataForId[i];
}
// Initialize the rest to zero
for (i++;i< arrayElems; i++) {
Id[i] = 0;
}
}
}
/**
* Returns the last index with a value different to zero.
* @param data Array to analyze.
* @return The last index of array with a value different to zero.
*/
private int getLastIndex(int[] data) {
int i = data.length - 1;
while (i > 0 && data[i] == 0) i--;
return i;
}
/**
* Translate the BigInteger <b>value</b> to an Id,
* partitioning it to fragments of 32 bits.
*/
protected void parseBigInteger(BigInteger value) {
Id = new int[arrayElems];
int[] data = new int[MAX_ARRAY_SIZE];
BigInteger two = new BigInteger("2");
BigInteger div = two.pow(MODULE);
//build entire identification with maximum precition
for (int i = 0; i < MAX_ARRAY_SIZE; i++) {
BigInteger[] result = value.divideAndRemainder(div);
data[i] = result[1].intValue();
value = result[0];
}
//transform the entire identification to fragment
//for actual presition bits.
translate(data);
}
/**
* Returns an Id corresponding to this Id plus a given offset
*
* @param offset the offset to add
* @return the new Id
*/
public Id add (Id offset) {
ChordId newId = new ChordId();
offsetId = (ChordId)offset;
long x;
long y;
long sum;
int carry = 0;
for (int i = 0; i < arrayElems; i++) {
// Little-endian to big-endian conversion
x = Id[i] & 0x0ffffffffL;
y = offsetId.Id[i] & 0x0ffffffffL;
sum = x + y + carry;
if (sum >= 0x100000000L) {
carry = 1;
} else {
carry = 0;
}
newId.Id[i] = (int) sum;
}
// Overflow: have to do modulus 2^bitLength
if (carry == 1) {
newId = (ChordId)newId.subtractWithCarry (getMaximum());
}
return newId;
}
public Id subtractWithCarry (Id offset) {
ChordId newId = new ChordId();
offsetId = (ChordId)offset;
int carry = 1;
long x;
long y;
long sub;
for (int i = 0; i < arrayElems; i++) {
x = Id[i] & 0x0ffffffffL;
// Consider carry bit to be added to Id (it is in fact out of range!)
if (i == arrayElems - 1) {
x |= 0x100000000L;
}
y = offsetId.Id[i] & 0x0ffffffffL;
sub = x - y - carry;
if (sub < 0) {
carry = 1;
}
newId.Id[i] = (int) sub;
}
return newId;
}
public Id subtract (Id offset) {
ChordId newId = new ChordId();
offsetId = (ChordId)offset;
int carry = 0;
long x;
long y;
long sub;
for (int i = 0; i < arrayElems; i++) {
x = Id[i] & 0x0ffffffffL;
y = offsetId.Id[i] & 0x0ffffffffL;
sub = x - y - carry;
if (sub < 0) {
carry = 1;
}
newId.Id[i] = (int) sub;
}
return newId;
}
public boolean equals (Object obj) {
ChordId nid = (ChordId) obj;
for (int i = 0; i < arrayElems; i++) {
if (Id[i] != nid.Id[i]) {
return false;
}
}
return true;
}
public void blit (byte target[]) {
for (int j = 0; j < bitsPerKey >> 3; j++) {
int k = Id[j >> 2] >> ((j % 4) * 8);
target[j] = (byte) (k & 0xff);
}
}
public byte[] copy() {
byte target[] = new byte[bitsPerKey >> 3];
blit(target);
return target;
}
/**
* Comparison operator for Ids. The comparison that occurs is a numerical comparison.
*
* @param obj the Id to compare with.
* @return negative if this < obj, 0 if they are equal and positive if this > obj.
*/
public int compareTo (Object obj) {
ChordId oth = (ChordId) obj;
for (int i = arrayElems - 1; i >= 0; i--) {
if (Id[i] != oth.Id[i]) {
long t = Id[i] & 0x0ffffffffL;
long o = oth.Id[i] & 0x0ffffffffL;
if (t < o) {
return -1;
} else {
return 1;
}
}
}
return 0;
}
/**
* Returns the byte array representation of this Id
*
* @return The byte array representation of this id
*/
public byte[] toByteArray() {
return copy();
}
/**
* Hash codes for Ids.
*
* @return a hash code.
*/
public int hashCode() {
int h = 0;
/// Hash function is computed by XORing the bits of the Id.
for (int i = 0; i < arrayElems; i++) {
h ^= Id[i];
}
return h;
}
/**
* Returns the complete represntation of this Id, in hex.
*
* @return The complete representation of this Id, in hexadecimal
*/
public String toStringHexFull() {
StringBuffer buffer = new StringBuffer();
String tran[] = {"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "A", "B", "C", "D", "E", "F"};
int n = bitsPerKey / 4;
for (int i = n - 1; i >= 0; i--) {
int d = getDigit(i, 4);
buffer.append(tran[d]);
}
return buffer.toString();
}
public String toStringFull() {
String hex = toStringHexFull();
java.math.BigInteger dec; // Decimal (base-10) equivalent of hexadecimal number.
int i; // A position in hex, from 0 to hex.length()-1.
dec = new java.math.BigInteger ("0");
for ( i = 0; i < hex.length(); i++ ) {
int digit = hexValue (hex.charAt(i));
dec = ((dec.multiply (new java.math.BigInteger("16"))).add (new java.math.BigInteger (""+digit)));
}
return dec.toString();
}
private int hexValue (char ch) {
// Returns the hexadecimal value of ch, or returns
// -1 if ch is not one of the hexadecimal digits.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -