⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chordid.java

📁 p2p仿真器。开发者可以工作在覆盖层中进行创造和测试逻辑算法或者创建和测试新的服务。PlanetSim还可以将仿真代码平稳转换为在Internet上的实验代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
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 + -