001: package org.garret.perst.impl;
002:
003: import org.garret.perst.*;
004:
005: import java.util.*;
006: import java.util.ArrayList;
007:
008: class RndBtreeCompoundIndex<T extends IPersistent> extends RndBtree<T>
009: implements Index<T> {
010: int[] types;
011:
012: RndBtreeCompoundIndex() {
013: }
014:
015: RndBtreeCompoundIndex(Class[] keyTypes, boolean unique) {
016: this .unique = unique;
017: type = ClassDescriptor.tpRaw;
018: types = new int[keyTypes.length];
019: for (int i = 0; i < keyTypes.length; i++) {
020: types[i] = getCompoundKeyComponentType(keyTypes[i]);
021: }
022: }
023:
024: static int getCompoundKeyComponentType(Class c) {
025: if (c.equals(Boolean.class)) {
026: return ClassDescriptor.tpBoolean;
027: } else if (c.equals(Byte.class)) {
028: return ClassDescriptor.tpByte;
029: } else if (c.equals(Character.class)) {
030: return ClassDescriptor.tpChar;
031: } else if (c.equals(Short.class)) {
032: return ClassDescriptor.tpShort;
033: } else if (c.equals(Integer.class)) {
034: return ClassDescriptor.tpInt;
035: } else if (c.equals(Long.class)) {
036: return ClassDescriptor.tpLong;
037: } else if (c.equals(Float.class)) {
038: return ClassDescriptor.tpFloat;
039: } else if (c.equals(Double.class)) {
040: return ClassDescriptor.tpDouble;
041: } else if (c.equals(String.class)) {
042: return ClassDescriptor.tpString;
043: } else if (c.equals(Date.class)) {
044: return ClassDescriptor.tpDate;
045: } else if (IPersistent.class.isAssignableFrom(c)) {
046: return ClassDescriptor.tpObject;
047: } else if (Comparable.class.isAssignableFrom(c)) {
048: return ClassDescriptor.tpRaw;
049: } else {
050: throw new StorageError(StorageError.UNSUPPORTED_INDEX_TYPE,
051: c);
052: }
053: }
054:
055: public Class[] getKeyTypes() {
056: Class[] keyTypes = new Class[types.length];
057: for (int i = 0; i < keyTypes.length; i++) {
058: keyTypes[i] = mapKeyType(types[i]);
059: }
060: return keyTypes;
061: }
062:
063: static class CompoundKey implements Comparable {
064: Object[] keys;
065:
066: public int compareTo(Object o) {
067: CompoundKey c = (CompoundKey) o;
068: int n = keys.length < c.keys.length ? keys.length
069: : c.keys.length;
070: for (int i = 0; i < n; i++) {
071: int diff = ((Comparable) keys[i]).compareTo(c.keys[i]);
072: if (diff != 0) {
073: return diff;
074: }
075: }
076: return 0; // allow to compare part of the compound key
077: }
078:
079: CompoundKey(Object[] keys) {
080: this .keys = keys;
081: }
082: }
083:
084: private Key convertKey(Key key) {
085: if (key == null) {
086: return null;
087: }
088: if (key.type != ClassDescriptor.tpArrayOfObject) {
089: throw new StorageError(StorageError.INCOMPATIBLE_KEY_TYPE);
090: }
091: return new Key(new CompoundKey((Object[]) key.oval),
092: key.inclusion != 0);
093: }
094:
095: public ArrayList<T> getList(Key from, Key till) {
096: return super .getList(convertKey(from), convertKey(till));
097: }
098:
099: public T get(Key key) {
100: return super .get(convertKey(key));
101: }
102:
103: public T remove(Key key) {
104: return super .remove(convertKey(key));
105: }
106:
107: public void remove(Key key, T obj) {
108: super .remove(convertKey(key), obj);
109: }
110:
111: public T set(Key key, T obj) {
112: return super .set(convertKey(key), obj);
113: }
114:
115: public boolean put(Key key, T obj) {
116: return super .put(convertKey(key), obj);
117: }
118:
119: public IterableIterator<T> iterator(Key from, Key till, int order) {
120: return super
121: .iterator(convertKey(from), convertKey(till), order);
122: }
123:
124: public IterableIterator<Map.Entry<Object, T>> entryIterator(
125: Key from, Key till, int order) {
126: return super.entryIterator(convertKey(from), convertKey(till),
127: order);
128: }
129: }
|