📄 linkedfile.java
字号:
{
throw new LinkedFileException("cycle in freelist "+thisFreeBuffer);
}
//visited[thisFreeBuffer] = thisFreeBuffer;
visited.put(new Long(thisFreeBuffer), new Long(thisFreeBuffer));
byte thetype = ((Byte) buffernumberToType.get(new Long(thisFreeBuffer))).byteValue();
//long NextBufferNumber = (long) buffernumberToNext[thisFreeBuffer];
long NextBufferNumber = ((Long) buffernumberToNext.get(new Long(thisFreeBuffer))).longValue();
if (thetype!=FREE)
{
throw new LinkedFileException("free list element not marked free "+thisFreeBuffer);
}
thisFreeBuffer = NextBufferNumber;
}
// traverse all nodes marked head
Hashtable allchunks = new Hashtable();
for (long buffernumber=0; buffernumber<LastBufferNumber; buffernumber++)
{
//byte thetype = (byte) buffernumberToType[buffernumber];
byte thetype = ((Byte) buffernumberToType.get(new Long(buffernumber))).byteValue();
if (thetype==HEAD)
{
if (visited.containsKey(new Long(buffernumber)))
{
throw new LinkedFileException("head buffer already visited "+buffernumber);
}
//allchunks[buffernumber] = buffernumber;
allchunks.put(new Long(buffernumber), new Long(buffernumber));
//visited[buffernumber] = buffernumber;
visited.put(new Long(buffernumber), new Long(buffernumber));
//long bodybuffernumber = (long) buffernumberToNext[buffernumber];
long bodybuffernumber = ((Long) buffernumberToNext.get(new Long(buffernumber))).longValue();
while (bodybuffernumber!=NULLBUFFERPOINTER)
{
//byte bodytype = (byte) buffernumberToType[bodybuffernumber];
byte bodytype = ((Byte) buffernumberToType.get(new Long(bodybuffernumber))).byteValue();
//long NextBufferNumber = (long) buffernumberToNext[bodybuffernumber];
long NextBufferNumber = ((Long) buffernumberToNext.get(new Long(bodybuffernumber))).longValue();
if (visited.containsKey(new Long(bodybuffernumber)))
{
throw new LinkedFileException("body buffer visited twice "+bodybuffernumber);
}
//visited[bodybuffernumber] = bodytype;
visited.put(new Long(bodybuffernumber), new Byte(bodytype));
if (bodytype!=BODY)
{
throw new LinkedFileException("body buffer not marked body "+thetype);
}
bodybuffernumber = NextBufferNumber;
}
// check retrieval
this.GetChunk(buffernumber);
}
}
// make sure all were visited
for (long buffernumber=0; buffernumber<LastBufferNumber; buffernumber++)
{
if (!visited.containsKey(new Long(buffernumber)))
{
throw new LinkedFileException("buffer not found either as data or free "+buffernumber);
}
}
// check against in use list
if (ChunksInUse!=null)
{
ArrayList notInUse = new ArrayList();
//foreach (DictionaryEntry d in ChunksInUse)
for (Enumeration e=ChunksInUse.keys(); e.hasMoreElements(); )
{
//long buffernumber = (long)d.Key;
long buffernumber = ( (Long) e.nextElement() ).longValue();
if (!allchunks.containsKey(new Long(buffernumber)))
{
//System.Diagnostics.Debug.WriteLine("\r\n<br>allocated chunks "+allchunks.Count);
//foreach (DictionaryEntry d1 in allchunks)
//{
// System.Diagnostics.Debug.WriteLine("\r\n<br>found "+d1.Key);
//}
throw new LinkedFileException("buffer in used list not found in linked file "+buffernumber);
}
}
//foreach (DictionaryEntry d in allchunks)
for (Enumeration e=allchunks.keys(); e.hasMoreElements(); )
{
//long buffernumber = (long)d.Key;
long buffernumber = ( (Long) e.nextElement() ).longValue();
if (!ChunksInUse.containsKey(new Long(buffernumber)))
{
if (!FixErrors)
{
throw new LinkedFileException("buffer in linked file not in used list "+buffernumber);
}
notInUse.add(new Long(buffernumber));
}
}
//notInUse.Sort();
//notInUse.Reverse();
//foreach (object thing in notInUse)
for (int iii=0; iii<notInUse.size(); iii++)
{
//long buffernumber = (long)thing;
long buffernumber = ( (Long) notInUse.get(iii) ).longValue();
this.ReleaseBuffers(buffernumber);
}
}
}
public byte[] GetChunk(long HeadBufferNumber)
throws Exception
{
// get the head, interpret the length
//byte buffertype;
//long NextBufferNumber;
//byte[] buffer = this.ParseBuffer(HeadBufferNumber, out buffertype, out NextBufferNumber);
ParseBuffer P = new ParseBuffer(HeadBufferNumber);
byte buffertype = P.type;
long NextBufferNumber = P.NextBufferNumber;
byte[] buffer = P.payload;
int length = BufferFile.Retrieve(buffer, 0);
if (length<0)
{
throw new LinkedFileException("negative length block? must be garbage: "+length);
}
if (buffertype!=HEAD)
{
throw new LinkedFileException("first buffer not marked HEAD");
}
byte[] result = new byte[length];
// read in the data from the first buffer
int firstLength = this.buffersize-BufferFile.INTSTORAGE;
if (firstLength>length)
{
firstLength = length;
}
//Array.Copy(buffer, BufferFile.INTSTORAGE, result, 0, firstLength);
for (int i=0; i<firstLength; i++)
{
result[i] = buffer[BufferFile.INTSTORAGE+i];
}
int stored = firstLength;
while (stored<length)
{
// get the next buffer
long thisBufferNumber = NextBufferNumber;
//buffer = this.ParseBuffer(thisBufferNumber, out buffertype, out NextBufferNumber);
P = new ParseBuffer(thisBufferNumber);
buffer = P.payload;
buffertype = P.type;
NextBufferNumber = P.NextBufferNumber;
int nextLength = this.buffersize;
if (length-stored<nextLength)
{
nextLength = length-stored;
}
//Array.Copy(buffer, 0, result, stored, nextLength);
for (int i=0; i<nextLength; i++)
{
result[stored+i] = buffer[i];
}
stored += nextLength;
}
return result;
}
public long StoreNewChunk(byte[] fromArray, int startingAt, int length)
throws Exception
{
// get the first buffer as result value
long currentBufferNumber = this.AllocateBuffer();
//System.Diagnostics.Debug.WriteLine(" allocating chunk starting at "+currentBufferNumber);
long result = currentBufferNumber;
if (length<0 || startingAt<0)
{
throw new LinkedFileException("cannot store negative length chunk ("+startingAt+","+length+")");
}
int endingAt = startingAt+length;
// special case: zero length chunk
if (endingAt>fromArray.length)
{
throw new LinkedFileException("array doesn't have this much data: "+endingAt);
}
int index = startingAt;
// store header with length information
byte[] buffer = new byte[this.buffersize];
BufferFile.Store(length, buffer, 0);
int fromIndex = startingAt;
int firstLength = this.buffersize-BufferFile.INTSTORAGE;
int stored = 0;
if (firstLength>length)
{
firstLength=length;
}
//Array.Copy(fromArray, fromIndex, buffer, BufferFile.INTSTORAGE, firstLength);
for (int i=0; i<firstLength; i++)
{
buffer[BufferFile.INTSTORAGE+i] = fromArray[i];
}
stored += firstLength;
fromIndex += firstLength;
byte CurrentBufferType = HEAD;
// store any remaining buffers (no length info)
while (stored<length)
{
// store current buffer and get next block number
long NextBufferNumber = this.AllocateBuffer();
this.SetBuffer(currentBufferNumber, CurrentBufferType, buffer, 0, buffer.length, NextBufferNumber);
currentBufferNumber = NextBufferNumber;
CurrentBufferType = BODY;
int nextLength = this.buffersize;
if (stored+nextLength>length)
{
nextLength = length-stored;
}
//Array.Copy(fromArray, fromIndex, buffer, 0, nextLength);
for (int i=0; i<nextLength; i++)
{
buffer[i] = fromArray[fromIndex+i];
}
stored += nextLength;
fromIndex += nextLength;
}
// store final buffer
this.SetBuffer(currentBufferNumber, CurrentBufferType, buffer, 0, buffer.length, NULLBUFFERPOINTER);
return result;
}
public void Flush()
throws Exception
{
if (this.headerDirty)
{
this.setHeader();
}
this.buffers.Flush();
}
public void ReleaseBuffers(long HeadBufferNumber)
throws Exception
{
// KISS
//System.Diagnostics.Debug.WriteLine(" deallocating chunk starting at "+HeadBufferNumber);
long thisbuffernumber = HeadBufferNumber;
//long NextBufferNumber;
//byte buffertype;
//byte[] dummy = this.ParseBuffer(HeadBufferNumber, out buffertype, out NextBufferNumber);
ParseBuffer P = new ParseBuffer(HeadBufferNumber);
long NextBufferNumber = P.NextBufferNumber;
byte buffertype = P.type;
if (buffertype!=HEAD)
{
throw new LinkedFileException("head buffer not marked HEAD");
}
this.DeallocateBuffer(HeadBufferNumber);
while (NextBufferNumber!=NULLBUFFERPOINTER)
{
thisbuffernumber = NextBufferNumber;
//dummy = this.ParseBuffer(thisbuffernumber, out buffertype, out NextBufferNumber);
P = new ParseBuffer(thisbuffernumber);
NextBufferNumber = P.NextBufferNumber;
buffertype = P.type;
if (buffertype!=BODY)
{
throw new LinkedFileException("body buffer not marked BODY");
}
this.DeallocateBuffer(thisbuffernumber);
}
}
}
/*
public class LinkedFileException: ApplicationException
{
public LinkedFileException(String message): base(message)
{
// do nothing extra
}
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -