📄 btreemultifieldindex.java
字号:
package org.garret.perst.impl;
import org.garret.perst.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.ArrayList;
class BtreeMultiFieldIndex<T extends IPersistent> extends Btree<T> implements FieldIndex<T> {
String className;
String[] fieldName;
int[] types;
transient Class cls;
transient Field[] fld;
BtreeMultiFieldIndex() {}
BtreeMultiFieldIndex(Class cls, String[] fieldName, boolean unique) {
this.cls = cls;
this.unique = unique;
this.fieldName = fieldName;
this.className = ClassDescriptor.getClassName(cls);
locateFields();
type = ClassDescriptor.tpArrayOfByte;
types = new int[fieldName.length];
for (int i = 0; i < types.length; i++) {
types[i] = checkType(fld[i].getType());
}
}
private final void locateFields()
{
fld = new Field[fieldName.length];
for (int i = 0; i < fieldName.length; i++) {
fld[i] = ClassDescriptor.locateField(cls, fieldName[i]);
if (fld[i] == null) {
throw new StorageError(StorageError.INDEXED_FIELD_NOT_FOUND, className + "." + fieldName[i]);
}
}
}
public Class getIndexedClass() {
return cls;
}
public Field[] getKeyFields() {
return fld;
}
public void onLoad()
{
cls = ClassDescriptor.loadClass(getStorage(), className);
locateFields();
}
int compareByteArrays(byte[] key, byte[] item, int offs, int lengtn) {
int o1 = 0;
int o2 = offs;
byte[] a1 = key;
byte[] a2 = item;
for (int i = 0; i < fld.length && o1 < key.length; i++) {
int diff = 0;
switch (types[i]) {
case ClassDescriptor.tpBoolean:
case ClassDescriptor.tpByte:
diff = a1[o1++] - a2[o2++];
break;
case ClassDescriptor.tpShort:
diff = Bytes.unpack2(a1, o1) - Bytes.unpack2(a2, o2);
o1 += 2;
o2 += 2;
break;
case ClassDescriptor.tpChar:
diff = (char)Bytes.unpack2(a1, o1) - (char)Bytes.unpack2(a2, o2);
o1 += 2;
o2 += 2;
break;
case ClassDescriptor.tpInt:
case ClassDescriptor.tpObject:
case ClassDescriptor.tpEnum:
{
int i1 = Bytes.unpack4(a1, o1);
int i2 = Bytes.unpack4(a2, o2);
diff = i1 < i2 ? -1 : i1 == i2 ? 0 : 1;
o1 += 4;
o2 += 4;
break;
}
case ClassDescriptor.tpLong:
case ClassDescriptor.tpDate:
{
long l1 = Bytes.unpack8(a1, o1);
long l2 = Bytes.unpack8(a2, o2);
diff = l1 < l2 ? -1 : l1 == l2 ? 0 : 1;
o1 += 8;
o2 += 8;
break;
}
case ClassDescriptor.tpFloat:
{
float f1 = Float.intBitsToFloat(Bytes.unpack4(a1, o1));
float f2 = Float.intBitsToFloat(Bytes.unpack4(a2, o2));
diff = f1 < f2 ? -1 : f1 == f2 ? 0 : 1;
o1 += 4;
o2 += 4;
break;
}
case ClassDescriptor.tpDouble:
{
double d1 = Double.longBitsToDouble(Bytes.unpack8(a1, o1));
double d2 = Double.longBitsToDouble(Bytes.unpack8(a2, o2));
diff = d1 < d2 ? -1 : d1 == d2 ? 0 : 1;
o1 += 8;
o2 += 8;
break;
}
case ClassDescriptor.tpString:
{
int len1 = Bytes.unpack4(a1, o1);
int len2 = Bytes.unpack4(a2, o2);
o1 += 4;
o2 += 4;
int len = len1 < len2 ? len1 : len2;
while (--len >= 0) {
diff = (char)Bytes.unpack2(a1, o1) - (char)Bytes.unpack2(a2, o2);
if (diff != 0) {
return diff;
}
o1 += 2;
o2 += 2;
}
diff = len1 - len2;
break;
}
case ClassDescriptor.tpArrayOfByte:
{
int len1 = Bytes.unpack4(a1, o1);
int len2 = Bytes.unpack4(a2, o2);
o1 += 4;
o2 += 4;
int len = len1 < len2 ? len1 : len2;
while (--len >= 0) {
diff = a1[o1++] - a2[o2++];
if (diff != 0) {
return diff;
}
}
diff = len1 - len2;
break;
}
default:
Assert.failed("Invalid type");
}
if (diff != 0) {
return diff;
}
}
return 0;
}
Object unpackByteArrayKey(Page pg, int pos) {
int offs = BtreePage.firstKeyOffs + BtreePage.getKeyStrOffs(pg, pos);
byte[] data = pg.data;
Object values[] = new Object[fld.length];
for (int i = 0; i < fld.length; i++) {
Object v = null;
switch (types[i]) {
case ClassDescriptor.tpBoolean:
v = Boolean.valueOf(data[offs++] != 0);
break;
case ClassDescriptor.tpByte:
v = new Byte(data[offs++]);
break;
case ClassDescriptor.tpShort:
v = new Short(Bytes.unpack2(data, offs));
offs += 2;
break;
case ClassDescriptor.tpChar:
v = new Character((char)Bytes.unpack2(data, offs));
offs += 2;
break;
case ClassDescriptor.tpInt:
v = new Integer(Bytes.unpack4(data, offs));
offs += 4;
break;
case ClassDescriptor.tpObject:
{
int oid = Bytes.unpack4(data, offs);
v = oid == 0 ? null : ((StorageImpl)getStorage()).lookupObject(oid, null);
offs += 4;
break;
}
case ClassDescriptor.tpLong:
v = new Long(Bytes.unpack8(data, offs));
offs += 8;
break;
case ClassDescriptor.tpEnum:
v = fld[i].getType().getEnumConstants()[Bytes.unpack4(data, offs)];
offs += 4;
break;
case ClassDescriptor.tpDate:
{
long msec = Bytes.unpack8(data, offs);
v = msec == -1 ? null : new Date(msec);
offs += 8;
break;
}
case ClassDescriptor.tpFloat:
v = new Float(Float.intBitsToFloat(Bytes.unpack4(data, offs)));
offs += 4;
break;
case ClassDescriptor.tpDouble:
v = new Double(Double.longBitsToDouble(Bytes.unpack8(data, offs)));
offs += 8;
break;
case ClassDescriptor.tpString:
{
int len = Bytes.unpack4(data, offs);
offs += 4;
char[] sval = new char[len];
for (int j = 0; j < len; j++) {
sval[j] = (char)Bytes.unpack2(data, offs);
offs += 2;
}
v = new String(sval);
break;
}
case ClassDescriptor.tpArrayOfByte:
{
int len = Bytes.unpack4(data, offs);
offs += 4;
byte[] bval = new byte[len];
System.arraycopy(data, offs, bval, 0, len);
offs += len;
break;
}
default:
Assert.failed("Invalid type");
}
values[i] = v;
}
return values;
}
private Key extractKey(IPersistent obj) {
try {
ByteBuffer buf = new ByteBuffer();
int dst = 0;
for (int i = 0; i < fld.length; i++) {
Field f = (Field)fld[i];
switch (types[i]) {
case ClassDescriptor.tpBoolean:
buf.extend(dst+1);
buf.arr[dst++] = (byte)(f.getBoolean(obj) ? 1 : 0);
break;
case ClassDescriptor.tpByte:
buf.extend(dst+1);
buf.arr[dst++] = f.getByte(obj);
break;
case ClassDescriptor.tpShort:
buf.extend(dst+2);
Bytes.pack2(buf.arr, dst, f.getShort(obj));
dst += 2;
break;
case ClassDescriptor.tpChar:
buf.extend(dst+2);
Bytes.pack2(buf.arr, dst, (short)f.getChar(obj));
dst += 2;
break;
case ClassDescriptor.tpInt:
buf.extend(dst+4);
Bytes.pack4(buf.arr, dst, f.getInt(obj));
dst += 4;
break;
case ClassDescriptor.tpObject:
{
IPersistent p = (IPersistent)f.get(obj);
buf.extend(dst+4);
if (p != null) {
if (!p.isPersistent())
{
getStorage().makePersistent(p);
}
Bytes.pack4(buf.arr, dst, p.getOid());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -