Added file locks to allow parallel access to chunks.

This allows a multi-threaded reading of chunks.
This commit is contained in:
Fredrik Blom 2012-11-15 10:11:23 +01:00
parent a002336603
commit 6326bdac82

View file

@ -21,6 +21,14 @@ 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.
/// </summary>
private object fileLock = new object();
private int[] offsets;
private int[] chunkTimestamps;
private List<Boolean> sectorFree;
@ -62,10 +70,12 @@ namespace Substrate.Core
// Cleanup unmanaged resources
if (file != null) {
lock (this.fileLock) {
file.Close();
file = null;
}
}
}
_disposed = true;
}
@ -93,6 +103,7 @@ namespace Substrate.Core
}
try {
lock (this.fileLock) {
file = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
//using (file) {
@ -161,7 +172,7 @@ namespace Substrate.Core
chunkTimestamps[i] = lastModValue;
}
//}
}
}
catch (IOException e) {
System.Console.WriteLine(e.Message);
@ -239,6 +250,7 @@ namespace Substrate.Core
return null;
}
lock (this.fileLock) {
file.Seek(sectorNumber * SectorBytes, SeekOrigin.Begin);
byte[] lengthBytes = new byte[4];
file.Read(lengthBytes, 0, 4);
@ -281,6 +293,7 @@ namespace Substrate.Core
Debugln("READ", x, z, "unknown version " + version);
return null;
}
}
catch (IOException) {
Debugln("READ", x, z, "exception");
return null;
@ -407,6 +420,7 @@ namespace Substrate.Core
* no free space large enough found -- we need to grow the
* file
*/
lock (this.fileLock) {
Debug("SAVE", x, z, length, "grow");
file.Seek(0, SeekOrigin.End);
sectorNumber = sectorFree.Count;
@ -420,6 +434,7 @@ namespace Substrate.Core
SetOffset(x, z, (sectorNumber << 8) | sectorsNeeded);
}
}
}
SetTimestamp(x, z, timestamp);
}
catch (IOException e) {
@ -430,6 +445,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 +458,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 +475,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 +495,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 +507,7 @@ namespace Substrate.Core
file.Write(bytes, 0, 4);
}
}
private int Timestamp ()
{
@ -507,6 +528,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 +540,14 @@ namespace Substrate.Core
file.Write(bytes, 0, 4);
}
}
public void Close ()
{
lock (this.fileLock) {
file.Close();
}
}
protected virtual int SectorBytes
{