📄 id.java
字号:
* @return the number of digits in that base */ public static int numDigits(int base) { return IdBitLength / base; } /** * Creates a random Id. For testing purposed only -- should NOT be used to * generate real node or object identifiers (low quality of random material). * * @param rng random number generator * @return a random Id */ public static Id makeRandomId(Random rng) { byte material[] = new byte[IdBitLength / 8]; rng.nextBytes(material); return build(material); } /** * DESCRIBE THE METHOD * * @param rng DESCRIBE THE PARAMETER * @return DESCRIBE THE RETURN VALUE */ public static Id makeRandomId(RandomSource rng) { byte material[] = new byte[IdBitLength / 8]; rng.nextBytes(material); return build(material); } // ----- SUPPORT FOR ID COALESCING ----- /** * Constructor. * * @param material an array of length at least IdBitLength/32 containing raw * Id material. * @return DESCRIBE THE RETURN VALUE */ public static Id build(int material[]) { return resolve(ID_MAP, new Id(material)); } /** * Id (Version 0) +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * + 160 Bit + + + + + + + + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * @param buf * @return DESCRIBE THE RETURN VALUE * @throws IOException */ public static Id build(rice.p2p.commonapi.rawserialization.InputBuffer buf) throws IOException { int[] material = new int[nlen]; for (int i = 0; i < material.length; i++) { material[i] = buf.readInt(); } return build(material); } /** * Constructor, which takes the output of a toStringFull() and converts it * back into an Id. Should not normally be used. * * @param hex The hexadeciaml representation from the toStringFull() * @return DESCRIBE THE RETURN VALUE */ public static Id build(String hex) { while (hex.length() < IdBitLength / 4) { hex = hex + "0"; } return build(hex.toUpperCase().toCharArray(), 0, hex.length()); } /** * Constructor, which takes the output of a toStringFull() and converts it * back into an Id. Should not normally be used. * * @param chars DESCRIBE THE PARAMETER * @param offset DESCRIBE THE PARAMETER * @param length DESCRIBE THE PARAMETER * @return DESCRIBE THE RETURN VALUE */ public static Id build(char[] chars, int offset, int length) { int[] array = new int[nlen]; for (int i = 0; i < nlen; i++) { for (int j = 0; j < 8; j++) { array[nlen - 1 - i] = (array[nlen - 1 - i] << 4) | trans(chars[offset + 8 * i + j]); } } return build(array); } /** * Internal method for mapping digit -> num * * @param c DESCRIBE THE PARAMETER * @return DESCRIBE THE RETURN VALUE */ protected static byte trans(char c) { if (('0' <= c) && ('9' >= c)) { return (byte) (c - '0'); } else { return (byte) (c - 'A' + 10); } } /** * Constructor. * * @param material an array of length at least IdBitLength/8 containing raw Id * material. * @return DESCRIBE THE RETURN VALUE */ public static Id build(byte[] material) { return build(trans(material)); } /** * Internal method for mapping byte[] -> int[] * * @param material The input byte[] * @return THe int[] */ protected static int[] trans(byte[] material) { int[] array = new int[nlen]; for (int j = 0; (j < IdBitLength / 8) && (j < material.length); j++) { int k = material[j] & 0xff; array[j / 4] |= k << ((j % 4) * 8); } return array; } /** * Constructor. It constructs a new Id with a value of 0 for all bits. * * @return DESCRIBE THE RETURN VALUE */ public static Id build() { return build(new int[nlen]); } /** * Static method for converting the hex representation into an array of ints. * * @param hex The hexadecimal represetnation * @return The cooresponding int array */ protected static int[] trans(String hex) { int[] ints = new int[nlen]; for (int i = 0; i < nlen; i++) { String s = hex.substring(i * 8, (i + 1) * 8); ints[nlen - 1 - i] = new java.math.BigInteger(s, 16).intValue(); } return ints; } /** * Method which performs the coalescing and interaction with the weak hash map * * @param id The Id to coalesce * @param map DESCRIBE THE PARAMETER * @return The Id to use */ protected static Id resolve(WeakHashMap map, Id id) { synchronized (map) { WeakReference ref = (WeakReference) map.get(id); Id result = null; if ((ref != null) && ((result = (Id) ref.get()) != null)) { return result; } else { map.put(id, new WeakReference(id)); return id; } } } /** * A class for representing and manipulating the distance between two Ids on * the circle. * * @version $Id: Id.java 3274 2006-05-15 16:17:47Z jeffh $ * @author amislove */ public static class Distance implements rice.p2p.commonapi.Id.Distance { private int difference[]; /** * Constructor. */ public Distance() { difference = new int[nlen]; } /** * Constructor. * * @param diff The different, as a byte array */ public Distance(byte[] diff) { difference = new int[nlen]; for (int j = 0; (j < IdBitLength / 8) && (j < diff.length); j++) { int k = diff[j] & 0xff; difference[j / 4] |= k << ((j % 4) * 8); } } /** * Constructor. * * @param diff The difference, as an int array */ public Distance(int[] diff) { difference = diff; } /** * Blits the distance into a target array. * * @param target an array of length at least IdBitLength/8 for the distance * to be stored in. */ public void blit(byte target[]) { blit(target, 0); } /** * Blits the distance into a target array, starting at the given offset. * * @param offset The offset to start at * @param target an array of length at least IdBitLength/8 for the distance * to be stored in. */ public void blit(byte target[], int offset) { for (int j = 0; j < IdBitLength / 8; j++) { int k = difference[j / 4] >> ((j % 4) * 8); target[offset + j] = (byte) (k & 0xff); } } /** * Copy the distance into a freshly generated array. * * @return a fresh copy of the distance material */ public byte[] copy() { byte target[] = new byte[IdBitLength / 8]; blit(target); return target; } /** * Comparison operator. The comparison that occurs is an absolute magnitude * comparison. * * @param obj the Distance to compare with. * @return negative if this < obj, 0 if they are equal and positive if this * > obj. */ public int compareTo(Object obj) { Distance oth = (Distance) obj; for (int i = nlen - 1; i >= 0; i--) { if (difference[i] != oth.difference[i]) { long t = difference[i] & 0x0ffffffffL; long o = oth.difference[i] & 0x0ffffffffL; if (t < o) { return -1; } else { return 1; } } } return 0; } /** * Equality operator. * * @param obj another Distance. * @return true if they are the same, false otherwise. */ public boolean equals(Object obj) { if (compareTo(obj) == 0) { return true; } else { return false; } } /** * Shift operator. shift(-1,0) multiplies value of this by two, shift(1,0) * divides by 2 * * @param cnt the number of bits to shift, negative shifts left, positive * shifts right * @param fill value of bit shifted in (0 if fill == 0, 1 otherwise) * @return this */ public Distance shift(int cnt, int fill) { return shift(cnt, fill, false); } /** * Shift operator. shift(-1,0) multiplies value of this by two, shift(1,0) * divides by 2 * * @param cnt the number of bits to shift, negative shifts left, positive * shifts right * @param fill value of bit shifted in (0 if fill == 0, 1 otherwise) * @param roundUp if true, round up the results after right shifting * @return this */ public Distance shift(int cnt, int fill, boolean roundUp) { int carry; int bit = 0; int lsb = 0; if (cnt > 0) { for (int j = 0; j < cnt; j++) { // shift right one bit carry = (fill == 0) ? 0 : 0x80000000; for (int i = nlen - 1; i >= 0; i--) { bit = difference[i] & 1; difference[i] = (difference[i] >>> 1) | carry; carry = (bit == 0) ? 0 : 0x80000000; } if (j == 0) { lsb = bit; } } if (roundUp && lsb > 0) { inc(); } } else { for (int j = 0; j < -cnt; j++) { // shift left one bit carry = (fill == 0) ? 0 : 1; for (int i = 0; i < nlen; i++) { bit = difference[i] & 0x80000000; difference[i] = (difference[i] << 1) | carry; carry = (bit == 0) ? 0 : 1; } } } return this; } /** * Hash codes. * * @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 < nlen; i++) { h ^= difference[i]; } return h; } /** * Returns a string representation of the distance The string is a byte * string from most to least significant. * * @return The string representation of this distance */ public String toString() { String s = "0x"; String tran[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}; for (int j = IdBitLength / 8 - 1; j >= 0; j--) { int k = difference[j / 4] >> ((j % 4) * 8); s = s + tran[(k >> 4) & 0x0f] + tran[k & 0x0f]; } return "< Id.distance " + s + " >"; } // common API Support /** * Shift operator. shift(-1,0) multiplies value of this by two, shift(1,0) * divides by 2 * * @param cnt the number of bits to shift, negative shifts left, positive * shifts right * @param fill value of bit shifted in (0 if fill == 0, 1 otherwise) * @return this */ public rice.p2p.commonapi.Id.Distance shiftDistance(int cnt, int fill) { return shift(cnt, fill); } /** * increment this distance */ private void inc() { long x; long sum; int carry = 1; // add one for (int i = 0; i < nlen; i++) { x = difference[i] & 0x0ffffffffL; sum = x + carry; if (sum >= 0x100000000L) { carry = 1; } else { carry = 0; } difference[i] = (int) sum; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -