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 */
017package org.apache.activemq.kaha.impl.index;
018
019import java.io.DataInput;
020import java.io.DataOutput;
021import java.io.IOException;
022
023import org.apache.activemq.kaha.StoreEntry;
024import org.apache.activemq.kaha.StoreLocation;
025import org.apache.activemq.kaha.impl.data.DataItem;
026import 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 */
033public 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}