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

📄 linkedfile.java

📁 R树与B树的混合树
💻 JAVA
📖 第 1 页 / 共 2 页
字号:


package NET.sourceforge.BplusJ.BplusJ;
import java.util.*;


	/// <summary>
	/// Chunked singly linked file with garbage collection.
	/// </summary>
	public class LinkedFile 
	{
		static long NULLBUFFERPOINTER = -1;
		//java.io.RandomAccessFile fromfile;
		java.io.RandomAccessFile fromfile;
		BufferFile buffers;
		int buffersize;
		int headersize;
		long seekStart = 0;
		long FreeListHead = NULLBUFFERPOINTER;
		long RecentNewBufferNumber = NULLBUFFERPOINTER;
		boolean headerDirty = true;
		byte FREE = 0;
		byte HEAD = 1;
		byte BODY = 2;
		public static byte[] HEADERPREFIX = { 98, 112, 78, 108, 102 };
		public static byte VERSION = 0;
		public static int MINBUFFERSIZE = 20;
		// next pointer and indicator flag
		public static int BUFFEROVERHEAD = BufferFile.LONGSTORAGE + 1;
		public LinkedFile(int buffersize, long seekStart)
			throws Exception
		{
			this.seekStart = seekStart;
			//this.buffers = buffers;
			this.buffersize = buffersize;
			// markers+version byte+buffersize+freelisthead
			this.headersize = HEADERPREFIX.length + 1 + BufferFile.INTSTORAGE + BufferFile.LONGSTORAGE; 
			this.sanityCheck();
		}
		public static LinkedFile SetupFromExistingStream(java.io.RandomAccessFile fromfile) 
			throws Exception
		{
			return SetupFromExistingStream(fromfile, (long)0);
		}
		public static LinkedFile SetupFromExistingStream(java.io.RandomAccessFile fromfile, long StartSeek) 
			throws Exception
		{
			LinkedFile result = new LinkedFile(100, StartSeek); // dummy buffer size for now
			result.fromfile = fromfile;
			result.readHeader();
			result.buffers = BufferFile.SetupFromExistingStream(fromfile, StartSeek+result.headersize);
			return result;
		}
		void readHeader() 
			throws Exception
		{
			byte[] header = new byte[this.headersize];
			//this.fromfile.Seek(this.seekStart, System.IO.SeekOrigin.Begin);
			this.fromfile.seek(this.seekStart);
			//this.fromfile.Read(header, 0, this.headersize);
			this.fromfile.read(header, 0, this.headersize);
			int index = 0;
			// check prefix
			//foreach (byte b in HEADERPREFIX) 
			for (int i=0; i<HEADERPREFIX.length; i++)
			{
				byte b = HEADERPREFIX[i];
				if (header[index]!=b) 
				{
					throw new LinkedFileException("invalid header prefix");
				}
				index++;
			}
			// skip version (for now)
			index++;
			// read buffersize
			this.buffersize = BufferFile.Retrieve(header, index);
			index += BufferFile.INTSTORAGE;
			this.FreeListHead = BufferFile.RetrieveLong(header, index);
			this.sanityCheck();
			this.headerDirty = false;
		}
		public static LinkedFile InitializeLinkedFileInStream(java.io.RandomAccessFile fromfile, int buffersize) 
			throws Exception
		{
			return InitializeLinkedFileInStream(fromfile, buffersize, (long)0);
		}
		public static LinkedFile InitializeLinkedFileInStream(java.io.RandomAccessFile fromfile, int buffersize, long StartSeek)
			throws Exception 
		{
			LinkedFile result = new LinkedFile(buffersize, StartSeek);
			result.fromfile = fromfile;
			result.setHeader();
			// buffersize should be increased by overhead...
			result.buffers = BufferFile.InitializeBufferFileInStream(fromfile, buffersize+BUFFEROVERHEAD, StartSeek+result.headersize);
			return result;
		}
		public void setHeader() 
			throws Exception
		{
			byte[] header = this.makeHeader();
			//this.fromfile.Seek(this.seekStart, System.IO.SeekOrigin.Begin);
			this.fromfile.seek(this.seekStart);
			//this.fromfile.Write(header, 0, header.length);
			this.fromfile.write(header, 0, header.length);
			this.headerDirty = false;
		}
		public byte[] makeHeader() 
			throws Exception
		{
			byte[] result = new byte[this.headersize];
			//HEADERPREFIX.CopyTo(result, 0);
			for (int i=0; i<HEADERPREFIX.length; i++) 
			{
				result[i] = HEADERPREFIX[i];
			}
			result[HEADERPREFIX.length] = VERSION;
			int index = HEADERPREFIX.length+1;
			BufferFile.Store(this.buffersize, result, index);
			index += BufferFile.INTSTORAGE;
			BufferFile.Store(this.FreeListHead, result, index);
			return result;
		}
		public void Recover(Hashtable ChunksInUse, boolean FixErrors) 
			throws Exception
		{
			// find missing space and recover it
			this.checkStructure(ChunksInUse, FixErrors);
		}
		void sanityCheck() 
			throws Exception
		{
			if (this.seekStart<0) 
			{
				throw new LinkedFileException("cannot seek negative "+this.seekStart);
			}
			if (this.buffersize<MINBUFFERSIZE) 
			{
				throw new LinkedFileException("buffer size too small "+this.buffersize);
			}
		}
		public void Shutdown()
			throws Exception
		{
			// flushing not needed in java
			//this.fromfile.Flush();
			this.fromfile.close();
		}
//		byte[] ParseBuffer(long bufferNumber, out byte type, out long NextBufferNumber) 
//		{
//			byte[] thebuffer = new byte[this.buffersize];
//			byte[] fullbuffer = new byte[this.buffersize+BUFFEROVERHEAD];
//			this.buffers.getBuffer(bufferNumber, fullbuffer, 0, fullbuffer.length);
//			type = fullbuffer[0];
//			NextBufferNumber = BufferFile.RetrieveLong(fullbuffer, 1);
//			Array.Copy(fullbuffer, BUFFEROVERHEAD, thebuffer, 0, this.buffersize);
//			return thebuffer;
//		}
		public class ParseBuffer 
		{
			public byte[] payload;
			public byte type;
			public long NextBufferNumber;
			public ParseBuffer(long bufferNumber) 
				throws Exception
			{
				byte[] thebuffer = new byte[LinkedFile.this.buffersize];
				byte[] fullbuffer = new byte[LinkedFile.this.buffersize+LinkedFile.BUFFEROVERHEAD];
				LinkedFile.this.buffers.getBuffer(bufferNumber, fullbuffer, 0, fullbuffer.length);
				this.type = fullbuffer[0];
				this.NextBufferNumber = BufferFile.RetrieveLong(fullbuffer, 1);
				for (int i=0; i<LinkedFile.this.buffersize; i++) 
				{
					thebuffer[i] = fullbuffer[i+LinkedFile.BUFFEROVERHEAD];
				}
				this.payload = thebuffer;
			}
		}
		void SetBuffer(long buffernumber, byte type, byte[] thebuffer, int start, int length, long NextBufferNumber)
			throws Exception
		{
			//System.Diagnostics.Debug.WriteLine(" storing chunk type "+type+" at "+buffernumber);
			if (this.buffersize<length) 
			{
				throw new LinkedFileException("buffer size too small "+this.buffersize+"<"+length);
			}
			byte[] fullbuffer = new byte[length+BUFFEROVERHEAD];
			fullbuffer[0] = type;
			BufferFile.Store(NextBufferNumber, fullbuffer, 1);
			if (thebuffer!=null) 
			{
				//Array.Copy(thebuffer, start, fullbuffer, BUFFEROVERHEAD, length);
				for (int i=0; i<length; i++) 
				{
					fullbuffer[BUFFEROVERHEAD+i] = thebuffer[i];
				}
			}
			this.buffers.setBuffer(buffernumber, fullbuffer, 0, fullbuffer.length);
		}

		void DeallocateBuffer(long buffernumber) 
			throws Exception
		{
			
			//System.Diagnostics.Debug.WriteLine(" deallocating "+buffernumber);
			// should be followed by resetting the header eventually.
			this.SetBuffer(buffernumber, FREE, null, 0, 0, this.FreeListHead);
			this.FreeListHead = buffernumber;
			this.headerDirty = true;
		}
		long AllocateBuffer() 
			throws Exception
		{
			if (this.FreeListHead!=NULLBUFFERPOINTER) 
			{
				// reallocate a freed buffer
				long result = this.FreeListHead;
				//byte buffertype;
				//long NextFree;
				//byte[] dummy = this.ParseBuffer(result, out buffertype, out NextFree);
				ParseBuffer P = new ParseBuffer(result);
				byte buffertype = P.type;
				long NextFree = P.NextBufferNumber;
				if (buffertype!=FREE) 
				{
					throw new LinkedFileException("free head buffer not marked free");
				}
				this.FreeListHead = NextFree;
				this.headerDirty = true;
				this.RecentNewBufferNumber = NULLBUFFERPOINTER;
				return result;
			} 
			else 
			{
				// allocate a new buffer
				long NextBufferNumber = this.buffers.nextBufferNumber();
				if (this.RecentNewBufferNumber==NextBufferNumber) 
				{
					// the previous buffer has been allocated but not yet written.  It must be written before the following one...
					NextBufferNumber++;
				}
				this.RecentNewBufferNumber = NextBufferNumber;
				return NextBufferNumber;
			}
		}
		public void checkStructure() 
			throws Exception
		{
			checkStructure(null, false);
		}
		public void checkStructure(Hashtable ChunksInUse, boolean FixErrors) 
			throws Exception
		{
			Hashtable buffernumberToType = new Hashtable();
			Hashtable buffernumberToNext = new Hashtable();
			Hashtable visited = new Hashtable();
			long LastBufferNumber = this.buffers.nextBufferNumber();
			for (long buffernumber=0; buffernumber<LastBufferNumber; buffernumber++) 
			{
				//byte buffertype;
				//long NextBufferNumber;
				//this.ParseBuffer(buffernumber, out buffertype, out NextBufferNumber);
				ParseBuffer P = new ParseBuffer(buffernumber);
				byte buffertype = P.type;
				long NextBufferNumber = P.NextBufferNumber;
				//buffernumberToType[buffernumber] = buffertype;
				buffernumberToType.put(new Long(buffernumber), new Byte(buffertype));
				//buffernumberToNext[buffernumber] = NextBufferNumber;
				buffernumberToNext.put(new Long(buffernumber), new Long(NextBufferNumber));
			}
			// traverse the freelist
			long thisFreeBuffer = this.FreeListHead;
			while (thisFreeBuffer!=NULLBUFFERPOINTER) 
			{
				if (visited.containsKey(new Long(thisFreeBuffer))) 

⌨️ 快捷键说明

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