recordstoreindex.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 480 行 · 第 1/2 页
JAVA
480 行
/* * * * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */package com.sun.midp.rms;import java.io.IOException;import javax.microedition.rms.*;import com.sun.midp.log.Logging;import com.sun.midp.log.LogChannels;/** * This class implements a record offset cache. It enables us to quickly * find offsets for records whose IDs we know. */class OffsetCache extends IntToIntMapper { /** * A special value for LastSeenOffset. * There's a database header at offset 0, and 0 means we have not seen any * records yet. */ static final int NO_OFFSET = 0; /** * After this offset there's no cached record IDs. * (An OffsetCache may cache offsets only for already seen records.) * The value NO_OFFSET is a special value for this variable: * NO_OFFSET means we have not seen any records yet. */ public int LastSeenOffset = NO_OFFSET; /** * Constructs an empty OffsetCache with the specified initial capacity and * capacity increment. * * @param initialCapacity the initial capacity * @param defaultElement the offset value that gets returned for * record IDs that are not there * @param capacityIncrement the amount by which the capacity is * increased when the mapper overflows. * (0 means "to be doubled") * @exception IllegalArgumentException if the specified initial capacity * is negative */ OffsetCache(int initialCapacity, int defaultElement, int capacityIncrement) { super(initialCapacity, defaultElement, capacityIncrement); }}/** * A class implementing a index of the record store. */class RecordStoreIndex { /** The Record Store that this object indexes */ private AbstractRecordStoreImpl recordStore; /** The Record Store database file */ private AbstractRecordStoreFile dbFile; /** specifies record ID to offset mapping */ private OffsetCache recordIdOffsets; /** * This value will be returned by recordIdOffsets.elementAt() when * record id is not found */ private static final int INVALID_OFFSET = -1; /** * Capacity increment for the offset cache. Zero indicates that capacity * has to be doubled each time. */ private static final int CACHE_CAPACITY_INCREMENT = 0; /** the initial record offset cache capacity */ private static final int INITIAL_CACHE_CAPACITY = 0x20; /** * Constructor for creating an index object for the given Record Store. * * @param rs record store that this object indexes * @param suiteId unique ID of the suite that owns the store * @param recordStoreName a string to name the record store */ RecordStoreIndex(AbstractRecordStoreImpl rs, int suiteId, String recordStoreName) throws IOException { recordStore = rs; dbFile = rs.getDbFile(); } /** * Closes the index file. * * @exception IOException if there are any file errors */ void close() throws IOException { } /** * Deletes index filed of named record store. There is no index * file in case of linear index implementation, thus makes * nothing. * * Called from RecordStoreImpl where record store files need to * be deleted. * * @param suiteId not used * @param recordStoreName not used * @return always <code>true</code> */ static boolean deleteIndex(int suiteId, String recordStoreName) { return true; } /** * Returns all of the recordId's currently in the record store index. * * @return an array of the recordId's currently in the index. */ int[] getRecordIDs() { int numRecordIDs = recordStore.getNumRecords(); int[] recordIDs = new int[numRecordIDs]; byte[] header = new byte[AbstractRecordStoreImpl.BLOCK_HEADER_SIZE]; int currentOffset = AbstractRecordStoreImpl.DB_HEADER_SIZE; int currentSize = 0; int currentRecordId = 0; int dbSize = recordStore.getSize(); int idx = 0; while (idx < numRecordIDs) { if (currentOffset >= dbSize) { // reached end of db file break; } try { // seek to the next offset currentOffset += currentSize; dbFile.seek(currentOffset); // read the block header if (dbFile.read(header) != AbstractRecordStoreImpl.BLOCK_HEADER_SIZE) { // error reading header break; } } catch (java.io.IOException ioe) { break; } currentRecordId = RecordStoreUtil.getInt(header, 0); if (currentRecordId > 0) { recordIDs[idx++] = currentRecordId; } currentSize = RecordStoreUtil. calculateBlockSize(RecordStoreUtil.getInt(header, 4)); } return recordIDs; } /** * Finds the record header for the given record and returns the * offset to the header. * * @param recordId the ID of the record to use in this operation * @param header a buffer that receives the header of the block * * @exception IOException if there is an error accessing the db file * @exception InvalidRecordIDException if the recordId is invalid * * @return the offset in the db file of the block added */ int getRecordHeader(int recordId, byte[] header) throws IOException, InvalidRecordIDException { if (recordId <= 0) { throw new InvalidRecordIDException("error finding record data"); } if (null != recordIdOffsets) { int offset = recordIdOffsets.elementAt(recordId); if (offset != recordIdOffsets.defaultValue) { dbFile.seek(offset); // read the block header if (dbFile.read(header) != AbstractRecordStoreImpl.BLOCK_HEADER_SIZE) { // did not find the recordId at the returned offset // throw away the index then! // (in principle, this should never happen) recordIdOffsets = null; } else { int foundId = RecordStoreUtil.getInt(header, 0); if (foundId == recordId) { return offset; } } } } if (null == recordIdOffsets) { recordIdOffsets = new OffsetCache(INITIAL_CACHE_CAPACITY, INVALID_OFFSET, CACHE_CAPACITY_INCREMENT); } return getRecordHeader_NoCache(recordId, header); } /** * A helper function for getRecordHeader().
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?