001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.activemq.kaha.impl.index;
018    
019    import java.io.DataInput;
020    import java.io.DataOutput;
021    import java.io.IOException;
022    
023    import org.apache.activemq.kaha.StoreEntry;
024    import org.apache.activemq.kaha.StoreLocation;
025    import org.apache.activemq.kaha.impl.data.DataItem;
026    import org.apache.activemq.kaha.impl.data.Item;
027    
028    /**
029     * A an Item with a relative position and location to other Items in the Store
030     * 
031     * 
032     */
033    public class IndexItem implements Item, StoreEntry {
034    
035        public static final int INDEX_SIZE = 51;
036        public static final int INDEXES_ONLY_SIZE = 19;
037    
038        protected long offset = POSITION_NOT_SET;
039    
040        // used by linked list
041        IndexItem next;
042        IndexItem prev;
043    
044        private long previousItem = POSITION_NOT_SET;
045        private long nextItem = POSITION_NOT_SET;
046        private boolean active = true;
047    
048        // TODO: consider just using a DataItem for the following fields.
049        private long keyOffset = POSITION_NOT_SET;
050        private int keyFile = (int)POSITION_NOT_SET;
051        private int keySize;
052    
053        private long valueOffset = POSITION_NOT_SET;
054        private int valueFile = (int)POSITION_NOT_SET;
055        private int valueSize;
056    
057        /**
058         * Default Constructor
059         */
060        public IndexItem() {
061        }
062    
063        void reset() {
064            previousItem = POSITION_NOT_SET;
065            nextItem = POSITION_NOT_SET;
066            keyOffset = POSITION_NOT_SET;
067            keyFile = (int)POSITION_NOT_SET;
068            keySize = 0;
069            valueOffset = POSITION_NOT_SET;
070            valueFile = (int)POSITION_NOT_SET;
071            valueSize = 0;
072            active = true;
073        }
074    
075        /**
076         * @return
077         * @see org.apache.activemq.kaha.StoreEntry#getKeyDataItem()
078         */
079        public StoreLocation getKeyDataItem() {
080            DataItem result = new DataItem();
081            result.setOffset(keyOffset);
082            result.setFile(keyFile);
083            result.setSize(keySize);
084            return result;
085        }
086    
087        /**
088         * @return
089         * @see org.apache.activemq.kaha.StoreEntry#getValueDataItem()
090         */
091        public StoreLocation getValueDataItem() {
092            DataItem result = new DataItem();
093            result.setOffset(valueOffset);
094            result.setFile(valueFile);
095            result.setSize(valueSize);
096            return result;
097        }
098    
099        public void setValueData(StoreLocation item) {
100            valueOffset = item.getOffset();
101            valueFile = item.getFile();
102            valueSize = item.getSize();
103        }
104    
105        public void setKeyData(StoreLocation item) {
106            keyOffset = item.getOffset();
107            keyFile = item.getFile();
108            keySize = item.getSize();
109        }
110    
111        /**
112         * @param dataOut
113         * @throws IOException
114         */
115        public void write(DataOutput dataOut) throws IOException {
116            dataOut.writeShort(MAGIC);
117            dataOut.writeBoolean(active);
118            dataOut.writeLong(previousItem);
119            dataOut.writeLong(nextItem);
120            dataOut.writeInt(keyFile);
121            dataOut.writeLong(keyOffset);
122            dataOut.writeInt(keySize);
123            dataOut.writeInt(valueFile);
124            dataOut.writeLong(valueOffset);
125            dataOut.writeInt(valueSize);
126        }
127    
128        void updateIndexes(DataOutput dataOut) throws IOException {
129            dataOut.writeShort(MAGIC);
130            dataOut.writeBoolean(active);
131            dataOut.writeLong(previousItem);
132            dataOut.writeLong(nextItem);
133        }
134    
135        /**
136         * @param dataIn
137         * @throws IOException
138         */
139        public void read(DataInput dataIn) throws IOException {
140            if (dataIn.readShort() != MAGIC) {
141                throw new BadMagicException();
142            }
143            active = dataIn.readBoolean();
144            previousItem = dataIn.readLong();
145            nextItem = dataIn.readLong();
146            keyFile = dataIn.readInt();
147            keyOffset = dataIn.readLong();
148            keySize = dataIn.readInt();
149            valueFile = dataIn.readInt();
150            valueOffset = dataIn.readLong();
151            valueSize = dataIn.readInt();
152        }
153    
154        void readIndexes(DataInput dataIn) throws IOException {
155            if (dataIn.readShort() != MAGIC) {
156                throw new BadMagicException();
157            }
158            active = dataIn.readBoolean();
159            previousItem = dataIn.readLong();
160            nextItem = dataIn.readLong();
161        }
162    
163        /**
164         * @param newPrevEntry
165         */
166        public void setPreviousItem(long newPrevEntry) {
167            previousItem = newPrevEntry;
168        }
169    
170        /**
171         * @return prev item
172         */
173        long getPreviousItem() {
174            return previousItem;
175        }
176    
177        /**
178         * @param newNextEntry
179         */
180        public void setNextItem(long newNextEntry) {
181            nextItem = newNextEntry;
182        }
183    
184        /**
185         * @return
186         * @see org.apache.activemq.kaha.StoreEntry#getNextItem()
187         */
188        public long getNextItem() {
189            return nextItem;
190        }
191    
192        /**
193         * @param newObjectOffset
194         */
195        void setKeyOffset(long newObjectOffset) {
196            keyOffset = newObjectOffset;
197        }
198    
199        /**
200         * @return key offset
201         */
202        long getKeyOffset() {
203            return keyOffset;
204        }
205    
206        /**
207         * @return
208         * @see org.apache.activemq.kaha.StoreEntry#getKeyFile()
209         */
210        public int getKeyFile() {
211            return keyFile;
212        }
213    
214        /**
215         * @param keyFile The keyFile to set.
216         */
217        void setKeyFile(int keyFile) {
218            this.keyFile = keyFile;
219        }
220    
221        /**
222         * @return
223         * @see org.apache.activemq.kaha.StoreEntry#getValueFile()
224         */
225        public int getValueFile() {
226            return valueFile;
227        }
228    
229        /**
230         * @param valueFile The valueFile to set.
231         */
232        void setValueFile(int valueFile) {
233            this.valueFile = valueFile;
234        }
235    
236        /**
237         * @return
238         * @see org.apache.activemq.kaha.StoreEntry#getValueOffset()
239         */
240        public long getValueOffset() {
241            return valueOffset;
242        }
243    
244        /**
245         * @param valueOffset The valueOffset to set.
246         */
247        public void setValueOffset(long valueOffset) {
248            this.valueOffset = valueOffset;
249        }
250    
251        /**
252         * @return Returns the active.
253         */
254        boolean isActive() {
255            return active;
256        }
257    
258        /**
259         * @param active The active to set.
260         */
261        void setActive(boolean active) {
262            this.active = active;
263        }
264    
265        /**
266         * @return
267         * @see org.apache.activemq.kaha.StoreEntry#getOffset()
268         */
269        public long getOffset() {
270            return offset;
271        }
272    
273        /**
274         * @param offset The offset to set.
275         */
276        public void setOffset(long offset) {
277            this.offset = offset;
278        }
279    
280        /**
281         * @return
282         * @see org.apache.activemq.kaha.StoreEntry#getKeySize()
283         */
284        public int getKeySize() {
285            return keySize;
286        }
287    
288        public void setKeySize(int keySize) {
289            this.keySize = keySize;
290        }
291    
292        /**
293         * @return
294         * @see org.apache.activemq.kaha.StoreEntry#getValueSize()
295         */
296        public int getValueSize() {
297            return valueSize;
298        }
299    
300        public void setValueSize(int valueSize) {
301            this.valueSize = valueSize;
302        }
303        
304        void copyIndex(IndexItem other) {
305            this.offset=other.offset;
306            this.active=other.active;
307            this.previousItem=other.previousItem;
308            this.nextItem=other.nextItem;
309        }
310    
311        /**
312         * @return print of 'this'
313         */
314        public String toString() {
315            String result = "offset=" + offset + ", key=(" + keyFile + ", " + keyOffset + ", " + keySize + ")" + ", value=(" + valueFile + ", " + valueOffset + ", " + valueSize + ")"
316                            + ", previousItem=" + previousItem + ", nextItem=" + nextItem;
317            return result;
318        }
319    
320        public boolean equals(Object obj) {
321            boolean result = obj == this;
322            if (!result && obj != null && obj instanceof IndexItem) {
323                IndexItem other = (IndexItem)obj;
324                result = other.offset == this.offset;
325            }
326            return result;
327        }
328    
329        public int hashCode() {
330            return (int)offset;
331        }
332    }