Author: vgritsenko Date: Sun Sep 2 03:14:13 2007 New Revision: 571938 URL: http://svn.apache.org/viewvc?rev=571938&view=rev Log: cleanup key - remove code duplication with value. make value completely immutable (barring byte array passed into constructor).
Modified: xml/xindice/trunk/java/src/org/apache/xindice/core/data/Entry.java xml/xindice/trunk/java/src/org/apache/xindice/core/data/Key.java xml/xindice/trunk/java/src/org/apache/xindice/core/data/Value.java xml/xindice/trunk/java/src/org/apache/xindice/core/filer/HashFiler.java xml/xindice/trunk/java/src/org/apache/xindice/core/filer/Paged.java Modified: xml/xindice/trunk/java/src/org/apache/xindice/core/data/Entry.java URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/data/Entry.java?rev=571938&r1=571937&r2=571938&view=diff ============================================================================== --- xml/xindice/trunk/java/src/org/apache/xindice/core/data/Entry.java (original) +++ xml/xindice/trunk/java/src/org/apache/xindice/core/data/Entry.java Sun Sep 2 03:14:13 2007 @@ -24,6 +24,7 @@ import java.util.Map; import java.util.HashMap; +import java.util.Collections; /** * Entry is a high-level representation of a database record, that includes @@ -33,12 +34,12 @@ */ public class Entry { - public static final byte UNKNOWN = 0; + public static final byte UNKNOWN = 0; public static final byte DOCUMENT = 1; - public static final byte BINARY = 2; - public static final byte OBJECT = 3; + public static final byte BINARY = 2; + public static final byte OBJECT = 3; - public static final String CREATED = "created"; + public static final String CREATED = "created"; public static final String MODIFIED = "modified"; private final Key key; @@ -46,6 +47,7 @@ private final Map meta; private final byte type; + public Entry(Key key, Document value, Map meta) { this.key = key; this.value = value; @@ -74,16 +76,16 @@ type = UNKNOWN; } - public byte getEntryType() { - return type; + public Key getKey() { + return key; } public Object getValue() { return value; } - public Key getKey() { - return key; + public Map getMeta() { + return Collections.unmodifiableMap(meta); } public long getCreationTime() { @@ -96,9 +98,13 @@ return date != null ? date.longValue() : 0; } + public byte getEntryType() { + return type; + } + public static Map createMetaMap(Record record) { Map entryMeta = new HashMap(); - entryMeta.put(Entry.CREATED, record.getMetaData(Record.CREATED)); + entryMeta.put(Entry.CREATED, record.getMetaData(Record.CREATED)); entryMeta.put(Entry.MODIFIED, record.getMetaData(Record.MODIFIED)); return entryMeta; } Modified: xml/xindice/trunk/java/src/org/apache/xindice/core/data/Key.java URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/data/Key.java?rev=571938&r1=571937&r2=571938&view=diff ============================================================================== --- xml/xindice/trunk/java/src/org/apache/xindice/core/data/Key.java (original) +++ xml/xindice/trunk/java/src/org/apache/xindice/core/data/Key.java Sun Sep 2 03:14:13 2007 @@ -19,7 +19,6 @@ package org.apache.xindice.core.data; - /** * Key extends Value by providing a hash value for the Key. * @@ -27,9 +26,6 @@ */ public final class Key extends Value { - private int hash; - - public Key(Value value) { super(value); } @@ -47,36 +43,15 @@ } public int getHash() { - // modeled after String.hashCode() - if (hash == 0) { - int tempHash = 0; - for(int i = 0 ; i < len; i++) { - tempHash = 31 * tempHash + data[pos + i]; - } - this.hash = Math.abs(tempHash); - } - return hash; + return super.hashCode(); } public boolean equals(Value value) { + //noinspection SimplifiableIfStatement if (value instanceof Key) { - Key key = (Key) value; - return getHash() == key.getHash() && compareTo(key) == 0; + return hashCode() == value.hashCode() && compareTo(value) == 0; } - return super.equals(value); - } - - public int hashCode() { - return getHash(); - } - - public boolean equals(Object obj) { - if (obj instanceof Value) { - return equals((Value) obj); - } - - return super.equals(obj); + return false; } } - Modified: xml/xindice/trunk/java/src/org/apache/xindice/core/data/Value.java URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/data/Value.java?rev=571938&r1=571937&r2=571938&view=diff ============================================================================== --- xml/xindice/trunk/java/src/org/apache/xindice/core/data/Value.java (original) +++ xml/xindice/trunk/java/src/org/apache/xindice/core/data/Value.java Sun Sep 2 03:14:13 2007 @@ -29,18 +29,26 @@ /** * Value is the primary base class for all data storing objects. - * The content window of Value objects are immutable, but the - * underlying byte array is not. + * The content window of value objects are immutable, but the + * underlying byte array which was used for constructing the value might be not. * * @version $Revision$, $Date$ */ public class Value implements Comparable { - protected byte[] data; - protected int pos; - protected int len; + private byte[] data; + private int pos; + private int len; private int hash; + /** + * Usually there is no need to create a copy of the value, since it is + * an immutable object. This constructor is mainly used to create + * key objects. + * + * @param value the value object which data will be used to construct this + * value. + */ public Value(Value value) { this.data = value.data; this.pos = value.pos; @@ -57,6 +65,7 @@ if (pos >= data.length || pos < 0 || pos + len > data.length) { throw new ArrayIndexOutOfBoundsException("Value cannot be created"); } + this.data = data; this.pos = pos; this.len = len; @@ -82,32 +91,23 @@ } /** - * getData retrieves the data being stored by the Value as a byte array. + * getData retrieves a <strong>copy</copy> of the data which is being stored + * by this value as a byte array. + * + * <p>Data copying is performed in order to ensure immutability of the Value. + * Avoid using this method if possible. * - * @return The Data + * @return The data */ public final byte[] getData() { - if (len != data.length) { - byte[] b = new byte[len]; - System.arraycopy(data, pos, b, 0, len); - return b; - } else { - return data; - } + byte[] b = new byte[len]; + System.arraycopy(data, pos, b, 0, len); + return b; } - /** - * Get a new Value that is part of this Value object. - * - * @param start beginning index - * @param len length of the new Value - * @return Value object - * @throws ArrayIndexOutOfBoundsException if start index is either negative - * or isn't less then length of original Value - */ - public final Value getSubvalue(int start, int len) { - return new Value(data, start, len); - } + // + // Data extraction + // /** * Returns the byte at the specified index. @@ -124,23 +124,60 @@ return data[pos + index]; } - public final boolean startsWith(Value value) { - if (len < value.len) { - return false; - } + /** + * Returns the short value at the specified index. + * + * @param index short index + * @return the short at the specified index. + * @throws ArrayIndexOutOfBoundsException if index is negative number or + * is not less that the length of the data array + */ + public final short shortAt(int index) { + return (short) ((data[index += pos] << 8) | data[index + 1]); + } - byte[] ddata = value.data; - int dpos = value.pos; + /** + * Returns the int value at the specified index. + * + * @param index int index + * @return the int at the specified index. + * @throws ArrayIndexOutOfBoundsException if index is negative number or + * is not less that the length of the data array + */ + public final int intAt(int index) { + return (short) ((data[index += pos] << 24) | (data[index + 1] << 16) | (data[index + 2] << 8) | data[index + 3]); + } - for (int i = 0; i < value.len; i++) { - if (data[i + pos] != ddata[i + dpos]) { - return false; - } - } + /** + * Get a value that is part of this value object. + * + * @param start beginning index + * @param len length of the new value + * @return Value object + * @throws ArrayIndexOutOfBoundsException if start index is either negative + * or isn't less then length of original Value + */ + public final Value valueAt(int start, int len) { + return new Value(data, pos + start, len); + } - return true; + /** + * Get a key that is part of this value object. + * + * @param start beginning index + * @param len length of the new key + * @return Key object + * @throws ArrayIndexOutOfBoundsException if start index is either negative + * or isn't less then length of original Value + */ + public final Key keyAt(int start, int len) { + return new Key(data, pos + start, len); } + // + // I/O + // + /** * Return an InputStream for the value. * @@ -154,6 +191,7 @@ * Stream the content of the value into an OutputStream. * * @param out the OutputStream + * @throws IOException if write failed */ public final void streamTo(OutputStream out) throws IOException { out.write(data, pos, len); @@ -181,6 +219,27 @@ System.arraycopy(data, pos, tdata, tpos, len); } + // + // Comparisons + // + + public final boolean startsWith(Value value) { + if (len < value.len) { + return false; + } + + byte[] ddata = value.data; + int dpos = value.pos; + + for (int i = 0; i < value.len; i++) { + if (data[i + pos] != ddata[i + dpos]) { + return false; + } + } + + return true; + } + public final int compareTo(Value value) { byte[] ddata = value.data; int dpos = value.pos; @@ -211,9 +270,26 @@ if (obj instanceof Value) { return compareTo((Value) obj); } + return compareTo(new Value(obj.toString())); } + // + // Object + // + + public int hashCode() { + // modeled after String.hashCode() + if (hash == 0) { + int tempHash = 0; + for (int i = 0; i < len; i++) { + tempHash = 31 * tempHash + data[pos + i]; + } + this.hash = Math.abs(tempHash); + } + return hash; + } + public boolean equals(Value value) { return len == value.len && compareTo(value) == 0; } @@ -222,22 +298,12 @@ if (this == obj) { return true; } + if (obj instanceof Value) { return equals((Value) obj); } - return obj != null && equals(new Value(obj.toString())); - } - public int hashCode() { - // modeled after String.hashCode() - if(hash == 0) { - int tempHash = 0; - for(int i = 0 ; i < len; i++) { - tempHash = 31 * tempHash + data[pos + i]; - } - this.hash = Math.abs(tempHash); - } - return hash; + return obj != null && equals(new Value(obj.toString())); } public final String toString() { Modified: xml/xindice/trunk/java/src/org/apache/xindice/core/filer/HashFiler.java URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/filer/HashFiler.java?rev=571938&r1=571937&r2=571938&view=diff ============================================================================== --- xml/xindice/trunk/java/src/org/apache/xindice/core/filer/HashFiler.java (original) +++ xml/xindice/trunk/java/src/org/apache/xindice/core/filer/HashFiler.java Sun Sep 2 03:14:13 2007 @@ -104,7 +104,7 @@ } private Page seekRecordPage(Key key) throws IOException { - int hash = key.getHash(); + int hash = key.hashCode(); long pageNum = hash % fileHeader.getPageCount(); Page p = getPage(pageNum); synchronized (p) { @@ -154,7 +154,7 @@ private Page seekInsertionPage(Key key) throws IOException { // Calculate hash and retrieve chain head page - int hash = key.getHash(); + int hash = key.hashCode(); Page p = getPage(hash % fileHeader.getPageCount()); // Synchronize by chain head page @@ -269,7 +269,7 @@ } checkOpened(); try { - int hash = key.getHash(); + int hash = key.hashCode(); long pageNum = hash % fileHeader.getPageCount(); Page page = getPage(pageNum); Modified: xml/xindice/trunk/java/src/org/apache/xindice/core/filer/Paged.java URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/filer/Paged.java?rev=571938&r1=571937&r2=571938&view=diff ============================================================================== --- xml/xindice/trunk/java/src/org/apache/xindice/core/filer/Paged.java (original) +++ xml/xindice/trunk/java/src/org/apache/xindice/core/filer/Paged.java Sun Sep 2 03:14:13 2007 @@ -1168,7 +1168,7 @@ // setKey WIPES OUT the Page data setRecordLen(0); dataLen = 0; - keyHash = key.getHash(); + keyHash = key.hashCode(); keyLen = (short) key.getLength(); dirty = true; }