From: Bryan T. <tho...@us...> - 2007-03-27 14:34:33
|
Update of /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv6186/src/java/com/bigdata/objndx Modified Files: IndexSegmentBuilder.java BTree.java IndexSegmentFileStore.java IIndex.java ReadOnlyFusedView.java AbstractBTree.java IndexSegmentExtensionMetadata.java ReadOnlyIndex.java BTreeMetadata.java IndexSegment.java IndexSegmentMetadata.java Log Message: Added indexUUID to AbstractBTree so that each scale-out index may have a unique indentifier. Modified the BTreeMetadata class and derived classes to use Externalizable, to support explicit versioning of the metadata record, and to have private fields since they can not be final with Externalizable. Index: IndexSegmentFileStore.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/IndexSegmentFileStore.java,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** IndexSegmentFileStore.java 15 Mar 2007 16:11:08 -0000 1.11 --- IndexSegmentFileStore.java 27 Mar 2007 14:34:22 -0000 1.12 *************** *** 172,176 **** try { ! Class cl = Class.forName(extensionMetadata.className); Constructor ctor = cl --- 172,176 ---- try { ! Class cl = Class.forName(extensionMetadata.getClassName()); Constructor ctor = cl Index: BTreeMetadata.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/BTreeMetadata.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** BTreeMetadata.java 15 Mar 2007 16:11:08 -0000 1.14 --- BTreeMetadata.java 27 Mar 2007 14:34:22 -0000 1.15 *************** *** 2,7 **** --- 2,13 ---- import java.io.Externalizable; + import java.io.IOException; + import java.io.ObjectInput; + import java.io.ObjectOutput; import java.io.Serializable; import java.nio.ByteBuffer; + import java.util.UUID; + + import org.CognitiveWeb.extser.LongPacker; import com.bigdata.io.SerializerUtil; *************** *** 14,22 **** * be re-loaded from the store. * </p> ! * ! * @todo The metadata record is extensible since it uses default java ! * serialization. That makes it a bit fat, which we could address by ! * implementing {@link Externalizable} but this is probably not much of an ! * issue. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> --- 20,28 ---- * be re-loaded from the store. * </p> ! * <p> ! * Note: Derived classes SHOULD extend the {@link Externalizable} interface and ! * explicitly manage serialization versions so that their metadata may evolve in ! * a backward compatible manner. ! * </p> * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> *************** *** 25,57 **** * @see BTree#newMetadata(), which you must override if you subclass this class. */ ! public class BTreeMetadata implements Serializable { private static final long serialVersionUID = 4370669592664382720L; ! /** ! * The address of the root node or leaf. ! */ ! public final long addrRoot; ! public final int branchingFactor; ! public final int height; ! public final int nnodes; ! public final int nleaves; ! public final int nentries; ! public final IValueSerializer valueSer; /** ! * The name of the class that will be used to re-load the index. */ ! public final String className; ! public final RecordCompressor recordCompressor; ! public final boolean useChecksum; /** --- 31,113 ---- * @see BTree#newMetadata(), which you must override if you subclass this class. */ ! public class BTreeMetadata implements Serializable, Externalizable { private static final long serialVersionUID = 4370669592664382720L; ! private long addrRoot; ! private int branchingFactor; ! private int height; ! private int nnodes; ! private int nleaves; ! private int nentries; ! private IValueSerializer valueSer; ! ! private String className; ! ! private RecordCompressor recordCompressor; ! ! private boolean useChecksum; ! ! private UUID indexUUID; /** ! * The address of the root node or leaf. */ ! public final long getRootAddr() { ! ! return addrRoot; ! ! } ! public final int getBranchingFactor() {return branchingFactor;} ! ! public final int getHeight() {return height;} ! public final int getNodeCount() {return nnodes;} ! ! public final int getLeafCount() {return nleaves;} ! ! public final int getEntryCount() {return nentries;} ! ! public final IValueSerializer getValueSerializer() {return valueSer;} ! ! /** ! * The name of a class derived from {@link BTree} that will be used to ! * re-load the index. ! */ ! public final String getClassName() {return className;} ! ! /** ! * The object that will handle record (de-)compressor -or- <code>null</code> ! * iff records are not compressed. ! */ ! public final RecordCompressor getRecordCompressor() {return recordCompressor;} ! ! /** ! * True iff node/leaf checksums are in use. ! */ ! public final boolean getUseChecksum() {return useChecksum;} ! ! /** ! * The unique identifier for the index whose data is accessible from this ! * metadata record. ! * <p> ! * All {@link AbstractBTree}s having data for the same index will have the ! * same {@link #indexUUID}. A partitioned index is comprised of mutable ! * {@link BTree}s and historical read-only {@link IndexSegment}s, all of ! * which will have the same {@link #indexUUID} if they have data for the ! * same scale-out index. ! */ ! public final UUID getIndexUUID() { ! ! return indexUUID; ! ! } /** *************** *** 73,82 **** } ! // /** ! // * De-serialization constructor. ! // */ ! // public BTreeMetadata() { ! // ! // } /** --- 129,138 ---- } ! /** ! * De-serialization constructor. ! */ ! public BTreeMetadata() { ! ! } /** *************** *** 110,113 **** --- 166,171 ---- this.useChecksum = btree.nodeSer.useChecksum; + this.indexUUID = btree.indexUUID; + /* * Note: This can not be invoked here since a derived class will not *************** *** 169,176 **** --- 227,301 ---- .getClass().getName())); sb.append(", useChecksum=" + useChecksum); + sb.append(", indexUUID="+indexUUID); return sb.toString(); } + + private static transient final int VERSION0 = 0x0; + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + + final int version = (int)LongPacker.unpackLong(in); + + if (version != VERSION0) { + + throw new IOException("Unknown version: version=" + version); + + } + + addrRoot = Addr.unpack(in); + + branchingFactor = (int)LongPacker.unpackLong(in); + + height = (int)LongPacker.unpackLong(in); + + nnodes = (int)LongPacker.unpackLong(in); + + nleaves = (int)LongPacker.unpackLong(in); + + nentries = (int)LongPacker.unpackLong(in); + + valueSer = (IValueSerializer)in.readObject(); + + className = in.readUTF(); + + recordCompressor = (RecordCompressor)in.readObject(); + + useChecksum = in.readBoolean(); + + indexUUID = new UUID(in.readLong()/*MSB*/,in.readLong()/*LSB*/); + + } + + public void writeExternal(ObjectOutput out) throws IOException { + + LongPacker.packLong(out,VERSION0); + + Addr.pack(out, addrRoot); + + LongPacker.packLong(out, branchingFactor); + + LongPacker.packLong(out, height); + + LongPacker.packLong(out, nnodes); + + LongPacker.packLong(out, nleaves); + + LongPacker.packLong(out, nentries); + + out.writeObject(valueSer); + + out.writeUTF(className); + + out.writeObject( recordCompressor ); + + out.writeBoolean(useChecksum); + + out.writeLong(indexUUID.getMostSignificantBits()); + + out.writeLong(indexUUID.getLeastSignificantBits()); + + } } Index: IIndex.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/IIndex.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** IIndex.java 8 Feb 2007 21:32:12 -0000 1.1 --- IIndex.java 27 Mar 2007 14:34:22 -0000 1.2 *************** *** 48,51 **** --- 48,53 ---- package com.bigdata.objndx; + import java.util.UUID; + /** * <p> *************** *** 59,61 **** --- 61,73 ---- public interface IIndex extends ISimpleBTree, IBatchBTree { + /** + * The unique identifier for the index whose data is stored in this B+Tree + * data structure. When using a scale-out index the same <i>indexUUID</i> + * MUST be assigned to each mutable and immutable B+Tree having data for any + * partition of that scale-out index. This makes it possible to work + * backwards from the B+Tree data structures and identify the index to which + * they belong. + */ + public UUID getIndexUUID(); + } Index: BTree.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/BTree.java,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** BTree.java 15 Mar 2007 16:11:08 -0000 1.39 --- BTree.java 27 Mar 2007 14:34:22 -0000 1.40 *************** *** 48,51 **** --- 48,52 ---- import java.lang.reflect.Constructor; + import java.util.UUID; import com.bigdata.cache.HardReferenceQueue; *************** *** 307,316 **** } - public NodeSerializer getNodeSerializer() { - - return nodeSer; - - } - /** * The metadata record used to load the last state of the index that was --- 308,311 ---- *************** *** 354,382 **** protected int nentries; - // public IAbstractNode getRoot() { - // - // return root; - // - // } - /** ! * Constructor for a new btree with a default hard reference queue policy * and no record compression. * * @param store * @param branchingFactor ! * @param valSer */ ! public BTree(IRawStore store, int branchingFactor, IValueSerializer valSer) { ! this(store, branchingFactor, new HardReferenceQueue<PO>( new DefaultEvictionListener(), BTree.DEFAULT_HARD_REF_QUEUE_CAPACITY, ! BTree.DEFAULT_HARD_REF_QUEUE_SCAN), valSer, null/*recordCompressor*/); } /** ! * Constructor for a new btree. * * @param store --- 349,380 ---- protected int nentries; /** ! * Constructor for a new B+Tree with a default hard reference queue policy * and no record compression. * * @param store + * The persistence store. * @param branchingFactor ! * The branching factor. ! * @param indexUUID ! * The unique identifier for the index. All B+Tree objects having ! * data for the same scale-out index MUST have the same ! * indexUUID. Otherwise a {@link UUID#randomUUID()} SHOULD be ! * used. ! * @param valueSer ! * Object that knows how to (de-)serialize the values in a ! * {@link Leaf}. */ ! public BTree(IRawStore store, int branchingFactor, UUID indexUUID, IValueSerializer valSer) { ! this(store, branchingFactor, indexUUID, new HardReferenceQueue<PO>( new DefaultEvictionListener(), BTree.DEFAULT_HARD_REF_QUEUE_CAPACITY, ! BTree.DEFAULT_HARD_REF_QUEUE_SCAN), valSer, null/* recordCompressor */); } /** ! * Constructor for a new B+Tree. * * @param store *************** *** 384,387 **** --- 382,390 ---- * @param branchingFactor * The branching factor. + * @param indexUUID + * The unique identifier for the index. All B+Tree objects having + * data for the same scale-out index MUST have the same + * indexUUID. Otherwise a {@link UUID#randomUUID()} SHOULD be + * used. * @param headReferenceQueue * The hard reference queue. The minimum capacity is 2 to avoid *************** *** 401,404 **** --- 404,408 ---- IRawStore store, int branchingFactor, + UUID indexUUID, HardReferenceQueue<PO> hardReferenceQueue, IValueSerializer valueSer, *************** *** 421,425 **** * has never been observed. */ ! !store.isFullyBuffered()/* useChecksum */ ); --- 425,430 ---- * has never been observed. */ ! !store.isFullyBuffered(),/* useChecksum */ ! indexUUID ); *************** *** 442,446 **** /** ! * Constructor for an existing btree. * * @param store --- 447,451 ---- /** ! * Load an existing B+Tree from the store. * * @param store *************** *** 451,471 **** * The hard reference queue for {@link Leaf}s. * ! * @see BTreeMetadata#load(IRawStore, long), which will re-load a ! * {@link BTree} or derived class from its {@link BTreeMetadata} ! * record. * * @see #newMetadata(), which must be overriden if you subclass * {@link BTreeMetadata} */ ! public BTree(IRawStore store, BTreeMetadata metadata, HardReferenceQueue<PO> hardReferenceQueue) { ! super(store, metadata.branchingFactor, 0/* initialBufferCapacity will be estimated */, hardReferenceQueue, PackedAddressSerializer.INSTANCE, ! metadata.valueSer, NodeFactory.INSTANCE, ! metadata.recordCompressor,// ! metadata.useChecksum // use checksum iff used on create. ); --- 456,477 ---- * The hard reference queue for {@link Leaf}s. * ! * @see #load(IRawStore, long), which will re-load a {@link BTree} or ! * derived class from the {@link Addr address} of its ! * {@link BTreeMetadata metadata} record. * * @see #newMetadata(), which must be overriden if you subclass * {@link BTreeMetadata} */ ! protected BTree(IRawStore store, BTreeMetadata metadata, HardReferenceQueue<PO> hardReferenceQueue) { ! super(store, metadata.getBranchingFactor(), 0/* initialBufferCapacity will be estimated */, hardReferenceQueue, PackedAddressSerializer.INSTANCE, ! metadata.getValueSerializer(), NodeFactory.INSTANCE, ! metadata.getRecordCompressor(),// ! metadata.getUseChecksum(), // use checksum iff used on create. ! metadata.getIndexUUID() ); *************** *** 474,481 **** // initialize mutable fields from the immutable metadata record. ! this.height = metadata.height; ! this.nnodes = metadata.nnodes; ! this.nleaves = metadata.nleaves; ! this.nentries = metadata.nentries; /* --- 480,487 ---- // initialize mutable fields from the immutable metadata record. ! this.height = metadata.getHeight(); ! this.nnodes = metadata.getNodeCount(); ! this.nleaves = metadata.getLeafCount(); ! this.nentries = metadata.getEntryCount(); /* *************** *** 541,545 **** */ ! root = readNodeOrLeaf(metadata.addrRoot); } --- 547,551 ---- */ ! root = readNodeOrLeaf(metadata.getRootAddr()); } *************** *** 650,654 **** if (metadata != null && (root == null || !root.dirty ! && metadata.addrRoot == root.getIdentity())) { /* --- 656,660 ---- if (metadata != null && (root == null || !root.dirty ! && metadata.getRootAddr() == root.getIdentity())) { /* *************** *** 727,731 **** try { ! Class cl = Class.forName(metadata.className); Constructor ctor = cl.getConstructor(new Class[] { --- 733,737 ---- try { ! Class cl = Class.forName(metadata.getClassName()); Constructor ctor = cl.getConstructor(new Class[] { Index: IndexSegmentBuilder.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/IndexSegmentBuilder.java,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** IndexSegmentBuilder.java 15 Mar 2007 16:11:08 -0000 1.28 --- IndexSegmentBuilder.java 27 Mar 2007 14:34:22 -0000 1.29 *************** *** 59,62 **** --- 59,63 ---- import java.text.NumberFormat; import java.util.NoSuchElementException; + import java.util.UUID; import org.apache.log4j.Level; *************** *** 198,201 **** --- 199,212 ---- /** + * The unique identifier for the index whose data is stored in this B+Tree + * data structure. When using a scale-out index the same <i>indexUUID</i> + * MUST be assigned to each mutable and immutable B+Tree having data for any + * partition of that scale-out index. This makes it possible to work + * backwards from the B+Tree data structures and identify the index to which + * they belong. + */ + final protected UUID indexUUID; + + /** * Used to serialize the nodes and leaves of the output tree. */ *************** *** 400,404 **** this(outFile, tmpDir, btree.getEntryCount(), btree.entryIterator(), m, btree.nodeSer.valueSerializer, true/* useChecksum */, ! null/* new RecordCompressor() */, errorRate); } --- 411,415 ---- this(outFile, tmpDir, btree.getEntryCount(), btree.entryIterator(), m, btree.nodeSer.valueSerializer, true/* useChecksum */, ! null/* new RecordCompressor() */, errorRate, btree.indexUUID); } *************** *** 448,451 **** --- 459,471 ---- * option should only be enabled if you know that point access * tests are a hotspot for an index. + * @param indexUUID + * The unique identifier for the index whose data is stored in + * this B+Tree data structure. When using a scale-out index the + * same <i>indexUUID</i> MUST be assigned to each mutable and + * immutable B+Tree having data for any partition of that + * scale-out index. This makes it possible to work backwards from + * the B+Tree data structures and identify the index to which + * they belong. See {@link AbstractBTree#getIndexUUID()}. + * * @throws IOException */ *************** *** 458,462 **** IEntryIterator entryIterator, final int m, IValueSerializer valueSerializer, boolean useChecksum, ! RecordCompressor recordCompressor, final double errorRate // , final Map<String, Serializable> metadataMap ) --- 478,483 ---- IEntryIterator entryIterator, final int m, IValueSerializer valueSerializer, boolean useChecksum, ! RecordCompressor recordCompressor, final double errorRate, ! final UUID indexUUID // , final Map<String, Serializable> metadataMap ) *************** *** 469,475 **** --- 490,498 ---- assert valueSerializer != null; assert errorRate >= 0d; + assert indexUUID != null; this.useChecksum = useChecksum; this.recordCompressor = recordCompressor; + this.indexUUID = indexUUID; final long begin = System.currentTimeMillis(); *************** *** 1452,1456 **** plan.nentries, maxNodeOrLeafLength, addrLeaves, addrNodes, addrRoot, addrExtensionMetadata, addrBloom, errorRate, out ! .length(), now); md.write(out); --- 1475,1479 ---- plan.nentries, maxNodeOrLeafLength, addrLeaves, addrNodes, addrRoot, addrExtensionMetadata, addrBloom, errorRate, out ! .length(), indexUUID, now); md.write(out); Index: IndexSegmentMetadata.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/IndexSegmentMetadata.java,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** IndexSegmentMetadata.java 8 Mar 2007 18:14:05 -0000 1.11 --- IndexSegmentMetadata.java 27 Mar 2007 14:34:23 -0000 1.12 *************** *** 43,47 **** * MUST be adjusted down from its original value of 256. */ ! static final int SIZEOF_UNUSED = 256; /** --- 43,47 ---- * MUST be adjusted down from its original value of 256. */ ! static final int SIZEOF_UNUSED = 240; /** *************** *** 52,56 **** SIZEOF_VERSION + // Bytes.SIZEOF_LONG + // timestamp0 ! Bytes.SIZEOF_UUID + // index segment UUID. SIZEOF_BRANCHING_FACTOR + // branchingFactor SIZEOF_COUNTS * 4 + // height, #leaves, #nodes, #entries --- 52,56 ---- SIZEOF_VERSION + // Bytes.SIZEOF_LONG + // timestamp0 ! Bytes.SIZEOF_UUID + // segment UUID. SIZEOF_BRANCHING_FACTOR + // branchingFactor SIZEOF_COUNTS * 4 + // height, #leaves, #nodes, #entries *************** *** 60,63 **** --- 60,64 ---- Bytes.SIZEOF_DOUBLE + // errorRate Bytes.SIZEOF_LONG + // file size + Bytes.SIZEOF_UUID + // index UUID. SIZEOF_UNUSED + // available bytes for future versions. Bytes.SIZEOF_LONG // timestamp1 *************** *** 75,81 **** /** ! * UUID for this {@link IndexSegment}. */ ! final public UUID uuid; /** --- 76,85 ---- /** ! * UUID for this {@link IndexSegment} (it is a unique identifier for ! * the index segment resource). ! * ! * @see #indexUUID */ ! final public UUID segmentUUID; /** *************** *** 171,174 **** --- 175,192 ---- /** + * The unique identifier for the index whose data is on this + * {@link IndexSegment}. + * <p> + * All {@link AbstractBTree}s having data for the same index will have the + * same {@link #indexUUID}. A partitioned index is comprised of mutable + * {@link BTree}s and historical read-only {@link IndexSegment}s, all of + * which will have the same {@link #indexUUID} if they have data for the + * same scale-out index. + * + * @see #segmentUUID + */ + final public UUID indexUUID; + + /** * Timestamp when the {@link IndexSegment} was generated. */ *************** *** 207,211 **** final long timestamp0 = raf.readLong(); ! uuid = new UUID(raf.readLong()/*MSB*/, raf.readLong()/*LSB*/); branchingFactor = raf.readInt(); --- 225,229 ---- final long timestamp0 = raf.readLong(); ! segmentUUID = new UUID(raf.readLong()/*MSB*/, raf.readLong()/*LSB*/); branchingFactor = raf.readInt(); *************** *** 242,245 **** --- 260,265 ---- } + indexUUID = new UUID(raf.readLong()/*MSB*/, raf.readLong()/*LSB*/); + raf.skipBytes(SIZEOF_UNUSED); *************** *** 266,270 **** int maxNodeOrLeafLength, long addrLeaves, long addrNodes, long addrRoot, long addrExtensionMetadata, long addrBloom, ! double errorRate, long length, long timestamp) { assert branchingFactor >= BTree.MIN_BRANCHING_FACTOR; --- 286,290 ---- int maxNodeOrLeafLength, long addrLeaves, long addrNodes, long addrRoot, long addrExtensionMetadata, long addrBloom, ! double errorRate, long length, UUID indexUUID, long timestamp) { assert branchingFactor >= BTree.MIN_BRANCHING_FACTOR; *************** *** 307,311 **** assert timestamp != 0L; ! this.uuid = UUID.randomUUID(); this.branchingFactor = branchingFactor; --- 327,331 ---- assert timestamp != 0L; ! this.segmentUUID = UUID.randomUUID(); this.branchingFactor = branchingFactor; *************** *** 337,340 **** --- 357,362 ---- this.length = length; + this.indexUUID = indexUUID; + this.timestamp = timestamp; *************** *** 359,365 **** raf.writeLong(timestamp); ! raf.writeLong(uuid.getMostSignificantBits()); ! raf.writeLong(uuid.getLeastSignificantBits()); raf.writeInt(branchingFactor); --- 381,387 ---- raf.writeLong(timestamp); ! raf.writeLong(segmentUUID.getMostSignificantBits()); ! raf.writeLong(segmentUUID.getLeastSignificantBits()); raf.writeInt(branchingFactor); *************** *** 390,393 **** --- 412,419 ---- raf.writeLong(length); + + raf.writeLong(indexUUID.getMostSignificantBits()); + + raf.writeLong(indexUUID.getLeastSignificantBits()); raf.skipBytes(SIZEOF_UNUSED); *************** *** 405,409 **** sb.append("magic="+Integer.toHexString(MAGIC)); ! sb.append(", uuid="+uuid); sb.append(", branchingFactor="+branchingFactor); sb.append(", height=" + height); --- 431,435 ---- sb.append("magic="+Integer.toHexString(MAGIC)); ! sb.append(", segmentUUID="+segmentUUID); sb.append(", branchingFactor="+branchingFactor); sb.append(", height=" + height); *************** *** 420,423 **** --- 446,450 ---- sb.append(", errorRate=" + errorRate); sb.append(", length=" + length); + sb.append(", indexUUID="+indexUUID); sb.append(", timestamp=" + new Date(timestamp)); Index: IndexSegmentExtensionMetadata.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/IndexSegmentExtensionMetadata.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** IndexSegmentExtensionMetadata.java 8 Mar 2007 18:14:05 -0000 1.1 --- IndexSegmentExtensionMetadata.java 27 Mar 2007 14:34:22 -0000 1.2 *************** *** 48,71 **** package com.bigdata.objndx; import java.io.Serializable; import com.bigdata.io.SerializerUtil; /** ! * The base class for variable length metadataMap and extension metadataMap for an ! * {@link IndexSegment} as persisted on an {@link IndexSegmentFileStore}. The ! * {@link IndexSegmentMetadata} class is NOT extensible and is used solely for ! * fixed length metadataMap common to all {@link IndexSegment}s, including the ! * root addresses required to bootstrap the load of an {@link IndexSegment} from ! * a file. In contrast, this class provides for both required variable length ! * metadataMap and arbitrary extension metadataMap for an {@link IndexSegment}. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ ! public class IndexSegmentExtensionMetadata implements Serializable { private static final long serialVersionUID = 4846316492768402991L; /** * Either {@link IndexSegment} or a derived class that will be instantiated --- 48,92 ---- package com.bigdata.objndx; + import java.io.Externalizable; + import java.io.IOException; + import java.io.ObjectInput; + import java.io.ObjectOutput; import java.io.Serializable; + import java.util.UUID; + + import org.CognitiveWeb.extser.LongPacker; import com.bigdata.io.SerializerUtil; /** ! * <p> ! * The base class for variable length metadata and extension metadata for an ! * {@link IndexSegment} as persisted on an {@link IndexSegmentFileStore}. ! * </p> ! * <p> ! * Note: The {@link IndexSegmentMetadata} class is NOT extensible and is used ! * solely for fixed length metadata common to all {@link IndexSegment}s, ! * including the root addresses required to bootstrap the load of an ! * {@link IndexSegment} from a file. In contrast, this class provides for both ! * required variable length metadata and arbitrary extension metadata for an ! * {@link IndexSegment}. ! * </p> ! * <p> ! * Note: Derived classes SHOULD extend the {@link Externalizable} interface and ! * explicitly manage serialization versions so that their metadata may evolve in ! * a backward compatible manner. ! * </p> * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ ! public class IndexSegmentExtensionMetadata implements Serializable, Externalizable { private static final long serialVersionUID = 4846316492768402991L; + private String className; + private IValueSerializer valSer; + private RecordCompressor recordCompressor; + /** * Either {@link IndexSegment} or a derived class that will be instantiated *************** *** 73,82 **** * {@link IndexSegmentFileStore#load()} */ ! public final String className; /** * The serializer used for the values in the leaves of the index. */ ! public final IValueSerializer valSer; /** --- 94,111 ---- * {@link IndexSegmentFileStore#load()} */ ! public final String getClassName() { ! ! return className; ! ! } /** * The serializer used for the values in the leaves of the index. */ ! public final IValueSerializer getValueSerializer() { ! ! return valSer; ! ! } /** *************** *** 86,114 **** * @todo modify to use an interface. */ ! final public RecordCompressor recordCompressor; ! ! // /** ! // * When non-null, a map containing extension metadata. ! // * ! // * @see #getMetadata(String name) ! // */ ! // final private Map<String, Serializable> metadataMap; ! // ! // /** ! // * Return the metadata object stored under the key. ! // * ! // * @param name ! // * The key. ! // * ! // * @return The metadata object or <code>null</code> if there is nothing ! // * stored under that key. ! // */ ! // public Serializable getMetadata(String name) { ! // ! // if(metadataMap==null) return null; ! // ! // return metadataMap.get(name); ! // ! // } /** --- 115,130 ---- * @todo modify to use an interface. */ ! final public RecordCompressor getRecordCompressor() { ! ! return recordCompressor; ! ! } ! ! /** ! * De-serialization constructor. ! */ ! public IndexSegmentExtensionMetadata() { ! ! } /** *************** *** 127,139 **** * write the nodes and leaves of the {@link IndexSegment}. */ - // * - // * @param metadataMap - // * An optional serializable map containing application defined - // * extension metadata. The map will be serialized with the - // * {@link IndexSegmentExtensionMetadata} object as part of the - // * {@link IndexSegmentFileStore}. public IndexSegmentExtensionMetadata(Class cl, IValueSerializer valSer, RecordCompressor recordCompressor) { - // Map<String, Serializable> metadataMap) { if( cl == null ) throw new IllegalArgumentException(); --- 143,148 ---- *************** *** 154,159 **** this.recordCompressor = recordCompressor; - // this.metadataMap = metadataMap; - } --- 163,166 ---- *************** *** 177,179 **** --- 184,218 ---- } + private static final transient int VERSION0 = 0x0; + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + + final int version = (int)LongPacker.unpackLong(in); + + if (version != VERSION0) { + + throw new IOException("Unknown version: version=" + version); + + } + + className = in.readUTF(); + + valSer = (IValueSerializer) in.readObject(); + + recordCompressor = (RecordCompressor) in.readObject(); + + } + + public void writeExternal(ObjectOutput out) throws IOException { + + LongPacker.packLong(out,VERSION0); + + out.writeUTF(className); + + out.writeObject(valSer); + + out.writeObject(recordCompressor); + + } + } Index: AbstractBTree.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/AbstractBTree.java,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** AbstractBTree.java 15 Mar 2007 16:11:08 -0000 1.20 --- AbstractBTree.java 27 Mar 2007 14:34:22 -0000 1.21 *************** *** 51,54 **** --- 51,55 ---- import java.nio.ByteBuffer; import java.util.Iterator; + import java.util.UUID; import org.apache.log4j.Level; *************** *** 144,147 **** --- 145,158 ---- /** + * The unique identifier for the index whose data is stored in this B+Tree + * data structure. When using a scale-out index the same <i>indexUUID</i> + * MUST be assigned to each mutable and immutable B+Tree having data for any + * partition of that scale-out index. This makes it possible to work + * backwards from the B+Tree data structures and identify the index to which + * they belong. + */ + final protected UUID indexUUID; + + /** * The branching factor for the btree. */ *************** *** 304,307 **** --- 315,326 ---- * reads are against memory which is presumably already parity * checked. + * @param indexUUID + * The unique identifier for the index whose data is stored in + * this B+Tree data structure. When using a scale-out index the + * same <i>indexUUID</i> MUST be assigned to each mutable and + * immutable B+Tree having data for any partition of that + * scale-out index. This makes it possible to work backwards from + * the B+Tree data structures and identify the index to which + * they belong. */ protected AbstractBTree(IRawStore store, int branchingFactor, *************** *** 310,314 **** IAddressSerializer addrSer, IValueSerializer valueSer, INodeFactory nodeFactory, RecordCompressor recordCompressor, ! boolean useChecksum) { assert store != null; --- 329,333 ---- IAddressSerializer addrSer, IValueSerializer valueSer, INodeFactory nodeFactory, RecordCompressor recordCompressor, ! boolean useChecksum, UUID indexUUID) { assert store != null; *************** *** 324,327 **** --- 343,348 ---- assert nodeFactory != null; + if(indexUUID == null) throw new IllegalArgumentException("indexUUID"); + this.store = store; *************** *** 334,337 **** --- 355,360 ---- valueSer, recordCompressor, useChecksum); + this.indexUUID = indexUUID; + } *************** *** 477,481 **** * {@link IIndex}. */ ! public NodeSerializer getNodeSerializer() { return nodeSer; --- 500,504 ---- * {@link IIndex}. */ ! final public NodeSerializer getNodeSerializer() { return nodeSer; *************** *** 484,487 **** --- 507,524 ---- /** + * The unique identifier for the index whose data is stored in this B+Tree + * data structure. When using a scale-out index the same <i>indexUUID</i> + * MUST be assigned to each mutable and immutable B+Tree having data for any + * partition of that scale-out index. This makes it possible to work + * backwards from the B+Tree data structures and identify the index to which + * they belong. + */ + final public UUID getIndexUUID() { + + return indexUUID; + + } + + /** * The root of the btree. This is initially a leaf until the leaf is split, * at which point it is replaced by a node. The root is also replaced each Index: IndexSegment.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/IndexSegment.java,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** IndexSegment.java 15 Mar 2007 16:11:08 -0000 1.18 --- IndexSegment.java 27 Mar 2007 14:34:22 -0000 1.19 *************** *** 132,139 **** new CustomAddressSerializer(Addr .getOffset(fileStore.metadata.addrNodes)), ! fileStore.extensionMetadata.valSer, ImmutableNodeFactory.INSTANCE, ! fileStore.extensionMetadata.recordCompressor, ! fileStore.metadata.useChecksum); // Type-safe reference to the backing store. --- 132,139 ---- new CustomAddressSerializer(Addr .getOffset(fileStore.metadata.addrNodes)), ! fileStore.extensionMetadata.getValueSerializer(), ImmutableNodeFactory.INSTANCE, ! fileStore.extensionMetadata.getRecordCompressor(), ! fileStore.metadata.useChecksum, fileStore.metadata.indexUUID); // Type-safe reference to the backing store. Index: ReadOnlyIndex.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/ReadOnlyIndex.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ReadOnlyIndex.java 17 Feb 2007 21:34:21 -0000 1.1 --- ReadOnlyIndex.java 27 Mar 2007 14:34:22 -0000 1.2 *************** *** 48,51 **** --- 48,53 ---- package com.bigdata.objndx; + import java.util.UUID; + /** * A fly-weight wrapper that does not permit write operations and reads *************** *** 66,69 **** --- 68,75 ---- } + + public UUID getIndexUUID() { + return src.getIndexUUID(); + } public boolean contains(byte[] key) { Index: ReadOnlyFusedView.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/ReadOnlyFusedView.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ReadOnlyFusedView.java 11 Mar 2007 11:41:45 -0000 1.1 --- ReadOnlyFusedView.java 27 Mar 2007 14:34:22 -0000 1.2 *************** *** 50,53 **** --- 50,54 ---- import java.util.Arrays; import java.util.NoSuchElementException; + import java.util.UUID; /** *************** *** 89,92 **** --- 90,99 ---- * for a given key by lookup() and which value is retained by * rangeQuery(). + * + * @exception IllegalArgumentException + * if a source is used more than once. + * @exception IllegalArgumentException + * unless all sources have the same + * {@link IIndex#getIndexUUID()} */ public ReadOnlyFusedView(final AbstractBTree[] srcs) { *************** *** 116,119 **** --- 123,131 ---- throw new IllegalArgumentException( "source used more than once"); + + if (srcs[i].getIndexUUID().equals(srcs[j].getIndexUUID())) { + throw new IllegalArgumentException( + "Sources have different index UUIDs"); + } } *************** *** 125,128 **** --- 137,144 ---- } + public UUID getIndexUUID() { + return srcs[0].getIndexUUID(); + } + /** * Write operations are not supported on the view. |