FileDocCategorySizeDatePackage
SimpleKeyGenerator.javaAPI DocGlassfish v2 API6520Fri May 04 22:32:56 BST 2007com.sun.ejb.base.sfsb.util

SimpleKeyGenerator

public class SimpleKeyGenerator extends Object implements com.sun.ejb.spi.sfsb.util.SFSBUUIDUtil
A utility class that generates stateful session keys using two longs The session id generated by this class is guarenteed to be unique as long as the system clock is never reset to a previous value The hashCode of the SessionKey generated by SimpleKeyGenerator also allows uniform distribution of keys when hashed in a HashMap
author
Mahesh Kannan

Fields Summary
protected long
prefix
protected long
suffix
protected int
idCounter
Constructors Summary
public SimpleKeyGenerator()

	long now = System.currentTimeMillis();
	now = ((int) (now >>> 32)) + ((int) now);
	scramble((int) now, System.identityHashCode(this));
    
public SimpleKeyGenerator(byte[] ipAddress, int port)

	scramble(Utility.bytesToInt(ipAddress, 0), port);
    
public SimpleKeyGenerator(long uniquePrefix)

	this.prefix = uniquePrefix;

	//Initial suffix
	this.suffix = System.currentTimeMillis();

	//Inital isCounter value
	this.idCounter = 0;

    
Methods Summary
public java.lang.ObjectbyteArrayToKey(byte[] array, int startIndex, int len)
Return the sessionKey that represents the sessionKey. This has to be super efficient as the container calls this method on every invocation. Two objects obtained from identical byte[] must satisfy both o1.equals(o2) and o1.hashCode() == o2.hashCode()

return
the sessionKey object

        long myPrefix = Utility.bytesToLong(array, startIndex);
        long mySuffix = Utility.bytesToLong(array, startIndex+8);
        int  myId = Utility.bytesToInt(array, startIndex+16);

        return new SimpleSessionKey(myPrefix, mySuffix, myId);
    
public java.lang.ObjectcreateSessionKey()
Create and return the sessionKey.

return
the sessionKey object

        int id = 0;
        synchronized (this) {
            id = idCounter++;
            if (id < 0) {
                //idCounter wrapped around!!
                id = idCounter = 0;
                suffix = System.currentTimeMillis();
            }
        }

        return new SimpleSessionKey(prefix, suffix, id);
    
public byte[]keyToByteArray(java.lang.Object sessionKey)
Called from the Container before publishing an IOR. The method must convert the sessionKey into a byte[]

return
A byte[] representation of the key. The byte[] could be created using serialization.

        SimpleSessionKey key = (SimpleSessionKey) sessionKey;
        byte[] array = new byte[20];

        Utility.longToBytes(key.prefix, array, 0);
        Utility.longToBytes(key.suffix, array, 8);
        Utility.intToBytes(key.id, array, 16);

        return array;
    
private voidscramble(int hi, int lo)

	byte[] hiBytes = new byte[4];
	Utility.intToBytes(hi, hiBytes, 0);
	byte[] loBytes = new byte[4];
	Utility.intToBytes(lo, loBytes, 0);

	swapBytes(hiBytes, loBytes, 2, 3);
	swapBytes(hiBytes, loBytes, 3, 0);
	swapBytes(hiBytes, loBytes, 1, 3);
	swapBytes(hiBytes, hiBytes, 0, 3);
	swapBytes(loBytes, loBytes, 2, 3);

        this.prefix = Utility.bytesToInt(hiBytes, 0);

        this.prefix = 
	    (this.prefix << 32) + Utility.bytesToInt(loBytes, 0);

        //Inital isCounter value
        this.idCounter = 0;

        //Set the default suffix value
        this.suffix = (int) System.currentTimeMillis();
    
private static final voidswapBytes(byte[] a, byte[] b, int index1, int index2)

	byte temp = a[index1];
	a[index1] = b[index2];
	b[index2] = temp;