final static int compare(Key key, Page pg, int i) { 
        long   i8;
        int    i4;
        float  r4;
        double r8;
        switch (key.type) {
          case ClassDescriptor.tpBoolean:
          case ClassDescriptor.tpByte:
            return (byte)key.ival - pg.data[BtreePage.firstKeyOffs + i];
          case ClassDescriptor.tpShort:
            return (short)key.ival - Bytes.unpack2(pg.data, BtreePage.firstKeyOffs + i*2);
          case ClassDescriptor.tpChar:
            return (char)key.ival - (char)Bytes.unpack2(pg.data, BtreePage.firstKeyOffs + i*2);
          case ClassDescriptor.tpObject:
          case ClassDescriptor.tpInt:
          case ClassDescriptor.tpEnum:
            i4 = Bytes.unpack4(pg.data, BtreePage.firstKeyOffs + i*4);
            return key.ival < i4 ? -1 : key.ival == i4 ? 0 : 1;
          case ClassDescriptor.tpLong:
          case ClassDescriptor.tpDate:
            i8 = Bytes.unpack8(pg.data, BtreePage.firstKeyOffs + i*8);
            return key.lval < i8 ? -1 : key.lval == i8 ? 0 : 1;
          case ClassDescriptor.tpFloat:
            r4 = Float.intBitsToFloat(Bytes.unpack4(pg.data, 
                                                    BtreePage.firstKeyOffs + i*4));
            return key.dval < r4 ? -1 : key.dval == r4 ? 0 : 1;
          case ClassDescriptor.tpDouble:
            r8 = Double.longBitsToDouble(Bytes.unpack8(pg.data, 
                                                       BtreePage.firstKeyOffs + i*8));
            return key.dval < r8 ? -1 : key.dval == r8 ? 0 : 1;
        }
        Assert.failed("Invalid type");
        return 0;
    }