⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recordstore.java

📁 有关j2me的很好的例子可以研究一下
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
     *     * @return a new record header      *         the record store's backing file.     */    private RecordHeader allocateNewRecordStorage(int id, int dataSize)	throws RecordStoreException, RecordStoreFullException    {	int allocSize = getAllocSize(dataSize);	boolean foundBlock = false;	/*	 * Traverse the free block linked list in the file, looking	 * for the first fit	 */	RecordHeader block = new RecordHeader();	try {	    int offset = dbFirstFreeBlockOffset;	    while (offset != 0) {		block.load(offset);		// If block is big enough, use it.		if (block.blockSize >= allocSize) {		    foundBlock = true;		    break; // use this free block		}		offset = block.dataLenOrNextFree; // next free block	    }	} catch (java.io.IOException ioe) {	    throw new RecordStoreException("error finding first fit block");	}		if (foundBlock == false) {	    	    /*	     * No free block was found that would hold this record, so	     * find the last (biggest offset) record in the file and	     * append this record after it.	     */	    	    // Is there room to grow the file?	    if (RecordStoreFile.spaceAvailable() < allocSize) {		throw new RecordStoreFullException();	    }	    	    block = new RecordHeader(dbDataEnd, id, 				     dbFirstRecordOffset,				     allocSize, dataSize);	    try {		block.store();	    } catch (java.io.IOException ioe) {		throw new RecordStoreException("error writing "+					       "new record data"); 	    }	    dbFirstRecordOffset = dbDataEnd;	    dbDataEnd += allocSize;	} else { 	    // block is where the new record should be stored	    if (block.id != -1) {		throw new RecordStoreException("ALLOC ERR " + block.id +					       " is not a free block!");	    }		    removeFreeBlock(block);  // remove from free block list	    	    	    block.id = id;	    if (block.blockSize - allocSize >=		DB_BLOCK_SIZE + DB_RECORD_HEADER_LENGTH) {		splitRecord(block, allocSize); // sets block.blockSize	    }	    block.dataLenOrNextFree = dataSize;	    try {		block.store(); 	    } catch (java.io.IOException ioe) {		throw new RecordStoreException("error writing free block "+					       "after alloc"); 	    }	}	// add new record to cache	recHeadCache.insert(block);	return block;    }    /**     * Splits a free block off the tail end of a large     * record block which contains extra free space.     * After calling this method, the caller must call      * <code>storeDBState</code>.     *     * On return, <code>recHead.blockSize</code> will contain     * allocSize.     *     * @param recHead the current record header     * @param allocSize the size that <code>recHEad</code>     *        will have as its <code>blockSize</code> variable     *        when the call returns.     *     * @exception RecordStoreException if there is an error     *            splitting the record     */    private void splitRecord(RecordHeader recHead, int allocSize)	throws RecordStoreException    {	RecordHeader newfb;		int extraSpace = recHead.blockSize - allocSize;	recHead.blockSize = allocSize;		// only split records inside the linked list	if (recHead.offset != dbFirstRecordOffset) {	    int fboffset = recHead.offset + allocSize;	    newfb = new RecordHeader(fboffset, -1, recHead.offset,				     extraSpace, 0);	    try {		freeRecord(newfb); // write new free block to disk		RecordHeader prh = new RecordHeader(recHead.offset +						    recHead.blockSize);		prh.nextOffset = fboffset;		prh.store();		recHeadCache.invalidate(prh.id);		storeDBState();	    } catch (java.io.IOException ioe) {		throw new RecordStoreException("splitRecord error");	    }	} else { 	    	    // drop free space at the end of the file	    dbDataEnd = recHead.offset + recHead.blockSize;	}    }	          /**     * Free a record into the Free list.       * Turns the RecordHeader block <code>rh</code> into a free      * block, then adds it to the free block linked list.       *     * After calling this method the caller must call      * <code>storeDBState</code>.     *     * @param rh RecordHeader of record to make into a free block     *     * @exception RecordStoreException if there is an IO error updating the      *            free list     */    private void freeRecord(RecordHeader rh) 	throws RecordStoreException    {	if (rh.offset == dbFirstRecordOffset) {	    // don't put free blocks at the end of the record file	    dbFirstRecordOffset = rh.nextOffset;	    dbDataEnd = rh.offset;	} else {	    rh.id = -1;  // indicate this is a free block	    rh.dataLenOrNextFree = dbFirstFreeBlockOffset;	    // insert this new free block at front of free list	    dbFirstFreeBlockOffset = rh.offset;	    try {		rh.store();	    } catch (java.io.IOException ioe) {		throw new RecordStoreException("free record failed");	    }	}    }    /**     * Remove a free block from the free block linked list     *     * @param blockToFree record header for the free block to remove     *      * @exception recordStoreException if error occurs during the     *            update.     */    private void removeFreeBlock(RecordHeader blockToFree) 	throws RecordStoreException     {	RecordHeader block = new RecordHeader();	RecordHeader prev = new RecordHeader();	RecordHeader tmp = null;	try {	    int offset = dbFirstFreeBlockOffset;	    while (offset != 0) {		block.load(offset);		if (block.offset == blockToFree.offset) {		    if (block.id != -1) {			throw new RecordStoreException("removeFreeBlock id" +						       " is not -1");		    }		    if (prev.offset == 0) {			// Set next free block as new freelist head			dbFirstFreeBlockOffset = block.dataLenOrNextFree;		    } else {			/*			 * Update previous block's pointer to the			 * block this block was pointing to			 */			prev.dataLenOrNextFree = block.dataLenOrNextFree;			prev.store();		    }		}		offset = block.dataLenOrNextFree;		// avoid creating lots of garbage!		tmp = prev;		prev = block;		block = tmp;	    }	} catch (java.io.IOException ioe) {	    throw new RecordStoreException("removeFreeBlock block not found");	}	    }    /**     * Helper method that stores the internal state variables     * into the record store file.     *     * checkopen should have been called.  will not work     * if dbraf is not open     *     * Updates dbLastModified time to current system time     */    private void storeDBState() throws RecordStoreException    {	try {	    // set modification time	    dbLastModified = System.currentTimeMillis();	    	    // Capture the db state into the byte array	    RecordStore.putInt(dbNumLiveRecords, dbState, RS_NUM_LIVE);	    RecordStore.putInt(0, dbState, RS_RESERVED); // reserved	    RecordStore.putInt(dbVersion, dbState, RS_VERSION);	    RecordStore.putInt(dbNextRecordID, dbState, RS_NEXT_ID);	    RecordStore.putInt(dbFirstRecordOffset, dbState, RS_REC_START);	    RecordStore.putInt(dbFirstFreeBlockOffset, dbState, RS_FREE_START);	    RecordStore.putLong(dbLastModified, dbState, RS_LAST_MODIFIED);	    RecordStore.putInt(dbDataStart, dbState, RS_DATA_START);	    RecordStore.putInt(dbDataEnd, dbState, RS_DATA_END);	    // Write the state to the db file	    dbraf.seek(SIGNATURE_LENGTH); // skip RS header 8 bytes	    int numbytes = DB_INIT.length - SIGNATURE_LENGTH;	    dbraf.write(dbState, SIGNATURE_LENGTH, numbytes);	} catch (java.io.IOException ioe) {	    throw new RecordStoreException("error writing record store " +					   "attributes");	}    }    /*     * Private Utility Methods     */    /**     * Throws a RecordStoreNotOpenException if the RecordStore     * is closed.  (A RecordStore is closed if the RecordStoreFile     * instance variable <code>dbraf</code> is null.     *     * @exception RecordStoreNotOpenException if RecordStore is closed     */    private void checkOpen() throws RecordStoreNotOpenException    {	if (dbraf == null)	    throw new RecordStoreNotOpenException();    }    /**     * Notifies all registered listeners that a record changed.     *     * @param recordId the record id of the changed record.     */    private void notifyRecordChangedListeners(int recordId)    {	for (int i = 0; i < recordListener.size(); i++) {	    RecordListener rl = (RecordListener)recordListener.elementAt(i);	    rl.recordChanged(this, recordId);	}    }    /**     * Notifies all registered listeners that a record was added.     *     * @param recordId the record id of the added record.     */    private void notifyRecordAddedListeners(int recordId)    {	for (int i = 0; i < recordListener.size(); i++) {	    RecordListener rl = (RecordListener)recordListener.elementAt(i);	    rl.recordAdded(this, recordId);	}    }        /**     * Notifies all registered listeners that a record was deleted.     *     * @param recordId the record id of the changed record.     */    private void notifyRecordDeletedListeners(int recordId)    {	for (int i = 0; i < recordListener.size(); i++) {	    RecordListener rl = (RecordListener)recordListener.elementAt(i);	    rl.recordDeleted(this, recordId);	}    }    /**     * A convenience method for converting a byte array into     * an int (assumes big-endian byte ordering).     *     * @param data the byte array returned from the database.     * @param offset the offset into the array of the first byte to start from.     *     * @return an int corresponding to the first four bytes      *         of the array passed in.     */    static int getInt(byte[] data, int offset)    {	int r = data[offset++];	r = (r << 8) | ((int)(data[offset++]) & 0xff);	r = (r << 8) | ((int)(data[offset++]) & 0xff);	r = (r << 8) | ((int)(data[offset++]) & 0xff);	return r;    }    /**     * A convenience method for converting a byte array into     * a long (assumes big-endian byte ordering).     *     * @param data the byte array returned from the database.     * @param offset the offset into the array of the first byte to start from.     * @return a long corresponding to the first eight bytes      *         of the array passed in.     */    static long getLong(byte[] data, int offset)    {	long r = data[offset++];	r = (r << 8) | ((long)(data[offset++]) & 0xff);	r = (r << 8) | ((long)(data[offset++]) & 0xff);	r = (r << 8) | ((long)(data[offset++]) & 0xff);	r = (r << 8) | ((long)(data[offset++]) & 0xff);	r = (r << 8) | ((long)(data[offset++]) & 0xff);	r = (r << 8) | ((long)(data[offset++]) & 0xff);	r = (r << 8) | ((long)(data[offset++]) & 0xff);	return r;    }    /**     * A convenience method for converting an integer into     * a byte array.     *     * @param i the integer to turn into a byte array.     * @param data a place to store the bytes of <code>i</code>.     * @param offset starting point within <code>data<code> to      *        store <code>i</code>.     *     * @return the number of bytes written to the array.     */    static int putInt(int i, byte[] data, int offset)    {	data[offset++] = (byte)((i >> 24) & 0xff);	data[offset++] = (byte)((i >> 16) & 0xff);	data[offset++] = (byte)((i >> 8) & 0xff);	data[offset] = (byte)(i & 0xff);	return 4;    }    /**     * A convenience method for converting a long into     * a byte array.     *     * @param l the <code>long<code> to turn into a byte array.     * @param data a place to store the bytes of <code>l</code>.     * @param offset Starting point within <code>data</code> to      *        store <code>l</code>.     *     * @return the number of bytes written to the array.     */    static int putLong(long l, byte[] data, int offset)    {	data[offset++] = (byte)((l >> 56) & 0xff);	data[offset++] = (byte)((l >> 48) & 0xff);	data[offset++] = (byte)((l >> 40) & 0xff);	data[offset++] = (byte)((l >> 32) & 0xff);	data[offset++] = (byte)((l >> 24) & 0xff);	data[offset++] = (byte)((l >> 16) & 0xff);	data[offset++] = (byte)((l >> 8) & 0xff);	data[offset] = (byte)(l & 0xff);	return 8;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -