A class to handle ULong64 return values in Java

The ULong64 type returned in statistics calls from the iControl API is necessary to track large numbers of bytes and connections, but is difficult to deal with from within Java.

Today we present you with one of the classes from the iControlIntermediary package that will handle ULong64 numbers for you in a sensical manner. This class will give you access to the data in the statistical return values without forcing you to write a ton of code - and that's what the iControl Java wrapper is all about, reducing the coding burden on you, so that you can concentrate on the problems of your business.

Our goals when building this class were twofold - first to make it broad enough to cover an array of possible uses, and second to make the ULong64 type usable without any jumping through hoops. Design considerations are simple - to extend the iControl ULong64 type and just add a couple of utility routines.

If you are planning on using the iControlIntermediary (working name) package when it becomes availalbe, then you won't need to copy this routine and add it to your own repertiore - it will be in the package. This class is not usable as-is - note the TODO: item to add your package name, and if you want to make it even more broadly applicable, you can fill out the TODO: to let the caller specify the precision of the output. We will before the first release of the code, but for now it suits our needs and other classes are taking priority.

 // TODO: add your package name here. 
import iControl.CommonULong64; // from the iControl JAR file or WSDL4J output source files, whichever you use.

public class UsefulU64 extends CommonULong64 {
// The following line is required of all serializable classes, but not utilized in our implementation. static final long serialVersionUID = 1;

static final short ONE_FOR_ONE = 0;
static final short KILOBYTES = 1;
static final short MEGABYTES = 2;
static final short GIGABYTES = 3;

public UsefulU64() { super(); }
public UsefulU64(long arg0, long arg1) { super(arg0, arg1); }
public UsefulU64(CommonULong64 orig) {
this.setHigh(orig.getHigh());
this.setLow(orig.getLow());
}

public Double doubleValue() {
long high = getHigh();
long low = getLow();
Double retVal;
// Since getHigh() and getLow() are declared as signed longs but hold unsigned data, make certain that we account for a long
// that rolled over into the negatives. An alternative to this would be to hand modify the WSDL4J output, but then we'd
// have to rewrite that code each time a new release of iControl came out. It is cleaner (in our opinion) to account for it here.
Double rollOver = new Double((double)0x7fffffff);
rollOver = new Double(rollOver.doubleValue() + 1.0);
if(high >=0)
retVal = new Double((high << 32 & 0xffff0000));
else
retVal = new Double(((high & 0x7fffffff) << 32) + (0x80000000 << 32));

if(low >=0)
retVal = new Double(retVal.doubleValue() + (double)low);
else
retVal = new Double(retVal.doubleValue() + (double)((low & 0x7fffffff)) + rollOver.doubleValue());

return retVal;
}

public String toString() {
String retString = null;
String size = "";
Double value = this.doubleValue();
double dval = value.doubleValue();

// Now scale the number to a displayable size.
if(dval / 1024 >= 1.0) {
size =
"K";
dval = dval / 1024;
}

if(dval / 1024 >= 1.0) {
size =
"M";
dval = dval / 1024;
}

if(dval / 1024 >= 1.0) {
size =
"G";
dval = dval / 1024;
}

// get the final version into a string with the decimal.

retString = new Double(dval).toString();

// eliminate excess digits past the decimal and add the units.
// TODO: make the number of significant digits and scaling factor configurable by user.

retString = retString.substring(0,retString.indexOf(".") + 2) + size;
return retString;
}
}

That's it - the class will build the Double for you, or build the String for you. For the vast majority of operations that is all that you need. We are using this class throughout both our Blackberry interface application and our Eclipse samples, and it works well.

This class is still being developed and is offered without any warranty (of course) - let us know if you have any problems with it or have ideas for making it better. Now while we're working on it is the best time to give input.
 

Published May 30, 2007
Version 1.0

Was this article helpful?

2 Comments

  • If using iControl.jar from Python/Jython, here is the helper class ported to Python:

     

     

    from iControl import CommonULong64

     

     

    class UsefulU64(object):

     

    def __init__(self,ulong=CommonULong64()):

     

    self.ulong=ulong

     

    self.value=0

     

     

    high=ulong.getHigh()

     

    low=ulong.getLow()

     

    rollOver = 0x7fffffff

     

    rollOver += 1

     

    tmpVal=0

     

    if(high >=0):

     

    tmpVal = high << 32 & 0xffff0000

     

    else:

     

    tmpVal = ((high & 0x7fffffff) << 32) + (0x80000000 << 32)

     

    if(low >=0):

     

    tmpVal = tmpVal + low

     

    else:

     

    tmpVal = tmpVal + (low & 0x7fffffff) + rollOver

     

     

    self.value=tmpVal

     

     

    def __str__(self):

     

    size = ""

     

    value=self.value

     

    if(value / 1024 >= 1.0):

     

    size = "K"

     

    value = value / 1024

     

    if(value / 1024 >= 1.0):

     

    size = "M"

     

    value = value / 1024

     

    if(value / 1024 >= 1.0):

     

    size = "G"

     

    value = value / 1024

     

    return "%.2f%s"%(value,size)

     

     

    if __name__ == "__main__":

     

    import iControl

     

    ic=iControl.Interfaces()

     

    ic.initialize("10.1.1.245","admin","admin")

     

    result=ic.localLBPool.get_all_statistics()

     

    stats=result.statistics

     

    print "Pool name: %s"%stats[0].pool_name

     

    print "Stats type: %s"%stats[0].statistics[0].type

     

    value=stats[0].statistics[0].value

     

    print "Stat value: %s"%UsefulU64(value)