forked from mirrors/NBTExplorer
Merge pull request #9 from z93blom/master
Added support for multithreaded access to chunks
This commit is contained in:
commit
44ff3373d0
1 changed files with 211 additions and 184 deletions
|
@ -21,6 +21,15 @@ namespace Substrate.Core
|
|||
|
||||
private string fileName;
|
||||
private FileStream file;
|
||||
|
||||
/// <summary>
|
||||
/// The file lock used so that we do not seek in different areas
|
||||
/// of the same file at the same time. All file access should lock this
|
||||
/// object before moving the file pointer.
|
||||
/// The lock should also surround all access to the sectorFree free variable.
|
||||
/// </summary>
|
||||
private object fileLock = new object();
|
||||
|
||||
private int[] offsets;
|
||||
private int[] chunkTimestamps;
|
||||
private List<Boolean> sectorFree;
|
||||
|
@ -62,10 +71,12 @@ namespace Substrate.Core
|
|||
|
||||
// Cleanup unmanaged resources
|
||||
if (file != null) {
|
||||
lock (this.fileLock) {
|
||||
file.Close();
|
||||
file = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
|
@ -93,6 +104,7 @@ namespace Substrate.Core
|
|||
}
|
||||
|
||||
try {
|
||||
lock (this.fileLock) {
|
||||
file = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
|
||||
|
||||
//using (file) {
|
||||
|
@ -161,7 +173,7 @@ namespace Substrate.Core
|
|||
|
||||
chunkTimestamps[i] = lastModValue;
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.Console.WriteLine(e.Message);
|
||||
|
@ -234,6 +246,8 @@ namespace Substrate.Core
|
|||
int sectorNumber = offset >> 8;
|
||||
int numSectors = offset & 0xFF;
|
||||
|
||||
lock (this.fileLock)
|
||||
{
|
||||
if (sectorNumber + numSectors > sectorFree.Count) {
|
||||
Debugln("READ", x, z, "invalid sector");
|
||||
return null;
|
||||
|
@ -281,6 +295,7 @@ namespace Substrate.Core
|
|||
Debugln("READ", x, z, "unknown version " + version);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (IOException) {
|
||||
Debugln("READ", x, z, "exception");
|
||||
return null;
|
||||
|
@ -368,6 +383,7 @@ namespace Substrate.Core
|
|||
else {
|
||||
/* we need to allocate new sectors */
|
||||
|
||||
lock (this.fileLock) {
|
||||
/* mark the sectors previously used for this chunk as free */
|
||||
for (int i = 0; i < sectorsAllocated; ++i) {
|
||||
sectorFree[sectorNumber + i] = true;
|
||||
|
@ -420,6 +436,7 @@ namespace Substrate.Core
|
|||
SetOffset(x, z, (sectorNumber << 8) | sectorsNeeded);
|
||||
}
|
||||
}
|
||||
}
|
||||
SetTimestamp(x, z, timestamp);
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
@ -430,6 +447,7 @@ namespace Substrate.Core
|
|||
/* write a chunk data to the region file at specified sector number */
|
||||
private void Write (int sectorNumber, byte[] data, int length)
|
||||
{
|
||||
lock (this.fileLock) {
|
||||
Debugln(" " + sectorNumber);
|
||||
file.Seek(sectorNumber * SectorBytes, SeekOrigin.Begin);
|
||||
|
||||
|
@ -442,9 +460,11 @@ namespace Substrate.Core
|
|||
file.WriteByte(VERSION_DEFLATE); // chunk version number
|
||||
file.Write(data, 0, length); // chunk data
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteChunk (int x, int z)
|
||||
{
|
||||
lock (this.fileLock) {
|
||||
int offset = GetOffset(x, z);
|
||||
int sectorNumber = offset >> 8;
|
||||
int sectorsAllocated = offset & 0xFF;
|
||||
|
@ -457,6 +477,7 @@ namespace Substrate.Core
|
|||
SetOffset(x, z, 0);
|
||||
SetTimestamp(x, z, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* is this an invalid chunk coordinate? */
|
||||
private bool OutOfBounds (int x, int z)
|
||||
|
@ -476,6 +497,7 @@ namespace Substrate.Core
|
|||
|
||||
private void SetOffset (int x, int z, int offset)
|
||||
{
|
||||
lock (this.fileLock) {
|
||||
offsets[x + z * 32] = offset;
|
||||
file.Seek((x + z * 32) * 4, SeekOrigin.Begin);
|
||||
|
||||
|
@ -487,6 +509,7 @@ namespace Substrate.Core
|
|||
|
||||
file.Write(bytes, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
private int Timestamp ()
|
||||
{
|
||||
|
@ -507,6 +530,7 @@ namespace Substrate.Core
|
|||
|
||||
public void SetTimestamp (int x, int z, int value)
|
||||
{
|
||||
lock (this.fileLock) {
|
||||
chunkTimestamps[x + z * 32] = value;
|
||||
file.Seek(SectorBytes + (x + z * 32) * 4, SeekOrigin.Begin);
|
||||
|
||||
|
@ -518,11 +542,14 @@ namespace Substrate.Core
|
|||
|
||||
file.Write(bytes, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
public void Close ()
|
||||
{
|
||||
lock (this.fileLock) {
|
||||
file.Close();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual int SectorBytes
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue