diff --git a/ClientNoSqlDB/Storage/FileSystem/DbTableStorage.cs b/ClientNoSqlDB/Storage/FileSystem/DbTableStorage.cs index a580beb..08a1e40 100644 --- a/ClientNoSqlDB/Storage/FileSystem/DbTableStorage.cs +++ b/ClientNoSqlDB/Storage/FileSystem/DbTableStorage.cs @@ -18,6 +18,10 @@ public DbTableStorage(string path, string name) readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); + public void Initialize() + { + + } public void Flush() { } @@ -61,7 +65,9 @@ public IDbTableReader BeginRead() _lock.EnterReadLock(); try { - return new Reader(this, _lock.ExitReadLock); + Reader reader = new Reader(this, _lock.ExitReadLock); + reader.Initialize(); + return reader; } catch { @@ -109,6 +115,10 @@ public Reader(DbTableStorage table, Action finalizer) { _table = table; _finalizer = finalizer; + } + + public void Initialize() + { CreateStreams(); UpdateTs(); } @@ -187,6 +197,7 @@ class Writer : Reader, IDbTableWriter public Writer(DbTableStorage table, Action finalizer) : base(table, finalizer) { + base.Initialize(); } protected override void CreateStreams() diff --git a/ClientNoSqlDB/Storage/Interfaces/IDbTableStorage.cs b/ClientNoSqlDB/Storage/Interfaces/IDbTableStorage.cs index 25177ac..e80583d 100644 --- a/ClientNoSqlDB/Storage/Interfaces/IDbTableStorage.cs +++ b/ClientNoSqlDB/Storage/Interfaces/IDbTableStorage.cs @@ -2,62 +2,63 @@ namespace ClientNoSqlDB { - /// - /// Table size information container - /// - public class DbTableInfo - { /// - /// Actual size of the index file + /// Table size information container /// - public long IndexSize; + public class DbTableInfo + { + /// + /// Actual size of the index file + /// + public long IndexSize; - /// - /// Actual size of the data file (including gaps) - /// - public long DataSize; + /// + /// Actual size of the data file (including gaps) + /// + public long DataSize; - /// - /// Effective size of the data file (excluding gaps) - /// - public long EffectiveDataSize; + /// + /// Effective size of the data file (excluding gaps) + /// + public long EffectiveDataSize; - /// - /// Summs all numeric properties - /// - public static DbTableInfo operator +(DbTableInfo a, DbTableInfo b) - { - return new DbTableInfo - { - DataSize = a.DataSize + b.DataSize, - IndexSize = a.IndexSize + b.IndexSize, - EffectiveDataSize = a.EffectiveDataSize + b.EffectiveDataSize - }; + /// + /// Summs all numeric properties + /// + public static DbTableInfo operator +(DbTableInfo a, DbTableInfo b) + { + return new DbTableInfo + { + DataSize = a.DataSize + b.DataSize, + IndexSize = a.IndexSize + b.IndexSize, + EffectiveDataSize = a.EffectiveDataSize + b.EffectiveDataSize + }; + } } - } - interface IDbTableStorage - { - IDbTableReader BeginRead(); - IDbTableWriter BeginWrite(); - IDbTableWriter BeginCompact(); - void Flush(); - } + interface IDbTableStorage + { + void Initialize(); + IDbTableReader BeginRead(); + IDbTableWriter BeginWrite(); + IDbTableWriter BeginCompact(); + void Flush(); + } - interface IDbTableReader : IDisposable - { - DateTimeOffset Ts { get; } - byte[] ReadIndex(); - byte[] ReadData(long position, int length); - DbTableInfo GetInfo(); - } + interface IDbTableReader : IDisposable + { + DateTimeOffset Ts { get; } + byte[] ReadIndex(); + byte[] ReadData(long position, int length); + DbTableInfo GetInfo(); + } - interface IDbTableWriter : IDbTableReader - { - DateTimeOffset WriteIndex(byte[] data, int length); - void WriteData(byte[] data, long position, int length); - void CopyData(long position, long target, int length); - void CropData(long position); - void Purge(); - } + interface IDbTableWriter : IDbTableReader + { + DateTimeOffset WriteIndex(byte[] data, int length); + void WriteData(byte[] data, long position, int length); + void CopyData(long position, long target, int length); + void CropData(long position); + void Purge(); + } } diff --git a/ClientNoSqlDB/Storage/IsolatedStorage/DbTableStorage.cs b/ClientNoSqlDB/Storage/IsolatedStorage/DbTableStorage.cs index 1c5d63f..dc0ea32 100644 --- a/ClientNoSqlDB/Storage/IsolatedStorage/DbTableStorage.cs +++ b/ClientNoSqlDB/Storage/IsolatedStorage/DbTableStorage.cs @@ -5,285 +5,297 @@ namespace ClientNoSqlDB.IsolatedStorage { - class DbTableStorage : IDbTableStorage - { - readonly IsolatedStorageFile _storage; - readonly string _indexName; - readonly string _dataName; - - public DbTableStorage(IsolatedStorageFile storage, string path, string name) + class DbTableStorage : IDbTableStorage { - _storage = storage; - _indexName = Path.Combine(path, name + ".index"); - _dataName = Path.Combine(path, name + ".data"); - } + readonly IsolatedStorageFile _storage; + readonly string _indexName; + readonly string _dataName; - readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); - - public void Flush() - { - } + public DbTableStorage(IsolatedStorageFile storage, string path, string name) + { + _storage = storage; + _indexName = Path.Combine(path, name + ".index"); + _dataName = Path.Combine(path, name + ".data"); + } - const int BufferSize = 256 * 1024; // 256K + readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); - Stream OpenRead(string name, bool buffered = false) - { - for (int i = 0; i < 10; i++) - try + public void Initialize() { - Stream s = _storage.OpenFile(name, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read); - return buffered ? new BufferedStream(s, BufferSize) : s; + } - catch (IsolatedStorageException) + + public void Flush() { - Thread.Sleep(100); } - throw new IOException("Cannot aquire read lock"); - } + const int BufferSize = 256 * 1024; // 256K - Stream OpenWrite(string name, bool buffered = false) - { - for (int i = 0; i < 10; i++) - try + Stream OpenRead(string name, bool buffered = false) { - Stream s = _storage.OpenFile(name, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); - return buffered ? new BufferedStream(s, BufferSize) : s; + for (int i = 0; i < 10; i++) + try + { + Stream s = _storage.OpenFile(name, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read); + return buffered ? new BufferedStream(s, BufferSize) : s; + } + catch (IsolatedStorageException) + { + Thread.Sleep(100); + } + + throw new IOException("Cannot aquire read lock"); } - catch (IsolatedStorageException) + + Stream OpenWrite(string name, bool buffered = false) { - Thread.Sleep(100); + for (int i = 0; i < 10; i++) + try + { + Stream s = _storage.OpenFile(name, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); + return buffered ? new BufferedStream(s, BufferSize) : s; + } + catch (IsolatedStorageException) + { + Thread.Sleep(100); + } + + throw new IOException("Cannot aquire read lock"); } - throw new IOException("Cannot aquire read lock"); - } - - public IDbTableReader BeginRead() - { - _lock.EnterReadLock(); - try - { - return new Reader(this, _lock.ExitReadLock); - } - catch - { - _lock.ExitReadLock(); - throw; - } - } - - public IDbTableWriter BeginWrite() - { - _lock.EnterWriteLock(); - try - { - return new Writer(this, _lock.ExitWriteLock); - } - catch - { - _lock.ExitWriteLock(); - throw; - } - } - - public IDbTableWriter BeginCompact() - { - _lock.EnterWriteLock(); - try - { - return new Compacter(this, _lock.ExitWriteLock); - } - catch - { - _lock.ExitWriteLock(); - throw; - } - } - - class Reader : IDbTableReader - { - protected Stream _readStream, _indexStream; - protected readonly DbTableStorage _table; - readonly Action _finalizer; - internal DateTimeOffset _ts; - - public Reader(DbTableStorage table, Action finalizer) - { - _table = table; - _finalizer = finalizer; - CreateStreams(); - UpdateTs(); - } - - protected void UpdateTs() - { - _ts = _table._storage.GetLastWriteTime(_table._indexName); - } - - protected virtual void CreateStreams() - { - _indexStream = _table.OpenRead(_table._indexName); - try + public IDbTableReader BeginRead() { - _readStream = _table.OpenRead(_table._dataName, true); + _lock.EnterReadLock(); + try + { + var reader = new Reader(this, _lock.ExitReadLock); + reader.Initialize(); + return reader; + } + catch + { + _lock.ExitReadLock(); + throw; + } } - catch + + public IDbTableWriter BeginWrite() { - _indexStream.Dispose(); - throw; + _lock.EnterWriteLock(); + try + { + return new Writer(this, _lock.ExitWriteLock); + } + catch + { + _lock.ExitWriteLock(); + throw; + } } - } - public DateTimeOffset Ts { get { return _ts; } } - - public DbTableInfo GetInfo() - { - return new DbTableInfo + public IDbTableWriter BeginCompact() { - DataSize = _readStream.Length, - IndexSize = _indexStream.Length - }; - } - - public byte[] ReadIndex() - { - if (_indexStream.Length == 0) - return null; - - var result = new byte[_indexStream.Length]; - _indexStream.Read(result, 0, result.Length); - return result; - } - - public byte[] ReadData(long position, int length) - { - if (_readStream.Position != position) - _readStream.Seek(position, SeekOrigin.Begin); - - var result = new byte[length]; - - _readStream.Read(result, 0, length); - - return result; - } - - public virtual void Dispose() - { - _readStream.Dispose(); - _indexStream.Dispose(); - - _finalizer(); - } - } - - class Writer : Reader, IDbTableWriter - { - Stream _writeStream; - - public Writer(DbTableStorage table, Action finalizer) - : base(table, finalizer) - { - } + _lock.EnterWriteLock(); + try + { + return new Compacter(this, _lock.ExitWriteLock); + } + catch + { + _lock.ExitWriteLock(); + throw; + } + } - protected override void CreateStreams() - { - _indexStream = _table.OpenWrite(_table._indexName); - try + class Reader : IDbTableReader { - _readStream = _table.OpenWrite(_table._dataName, true); - _writeStream = _readStream; + protected Stream _readStream, _indexStream; + protected readonly DbTableStorage _table; + readonly Action _finalizer; + internal DateTimeOffset _ts; + + public Reader(DbTableStorage table, Action finalizer) + { + _table = table; + _finalizer = finalizer; + } + + + public void Initialize() + { + CreateStreams(); + UpdateTs(); + } + + protected void UpdateTs() + { + _ts = _table._storage.GetLastWriteTime(_table._indexName); + } + + protected virtual void CreateStreams() + { + _indexStream = _table.OpenRead(_table._indexName); + try + { + _readStream = _table.OpenRead(_table._dataName, true); + } + catch + { + _indexStream.Dispose(); + throw; + } + } + + public DateTimeOffset Ts { get { return _ts; } } + + public DbTableInfo GetInfo() + { + return new DbTableInfo + { + DataSize = _readStream.Length, + IndexSize = _indexStream.Length + }; + } + + public byte[] ReadIndex() + { + if (_indexStream.Length == 0) + return null; + + var result = new byte[_indexStream.Length]; + _indexStream.Read(result, 0, result.Length); + return result; + } + + public byte[] ReadData(long position, int length) + { + if (_readStream.Position != position) + _readStream.Seek(position, SeekOrigin.Begin); + + var result = new byte[length]; + + _readStream.Read(result, 0, length); + + return result; + } + + public virtual void Dispose() + { + _readStream.Dispose(); + _indexStream.Dispose(); + + _finalizer(); + } } - catch + + class Writer : Reader, IDbTableWriter { - _indexStream.Dispose(); - throw; + Stream _writeStream; + + public Writer(DbTableStorage table, Action finalizer) + : base(table, finalizer) + { + } + + protected override void CreateStreams() + { + _indexStream = _table.OpenWrite(_table._indexName); + try + { + _readStream = _table.OpenWrite(_table._dataName, true); + _writeStream = _readStream; + } + catch + { + _indexStream.Dispose(); + throw; + } + } + + public DateTimeOffset WriteIndex(byte[] data, int length) + { + _indexStream.SetLength(0); + _indexStream.Write(data, 0, length); + _indexStream.Dispose(); + + UpdateTs(); + + return _ts; + } + + public void CopyData(long position, long target, int length) + { + var data = new byte[length]; + + if (_readStream.Position != position) + _readStream.Seek(position, SeekOrigin.Begin); + + _readStream.Read(data, 0, length); + + if (_writeStream.Position != target) + _writeStream.Seek(target, SeekOrigin.Begin); + + _writeStream.Write(data, 0, length); + } + + public void WriteData(byte[] data, long position, int length) + { + if (_writeStream.Position != position) + _writeStream.Seek(position, SeekOrigin.Begin); + + _writeStream.Write(data, 0, length); + } + + public void Purge() + { + _writeStream.SetLength(0); + _indexStream.SetLength(0); + } + + public void CropData(long size) + { + _writeStream.SetLength(size); + } + + public override void Dispose() + { + _writeStream.Dispose(); + base.Dispose(); + } } - } - - public DateTimeOffset WriteIndex(byte[] data, int length) - { - _indexStream.SetLength(0); - _indexStream.Write(data, 0, length); - _indexStream.Dispose(); - - UpdateTs(); - - return _ts; - } - public void CopyData(long position, long target, int length) - { - var data = new byte[length]; - - if (_readStream.Position != position) - _readStream.Seek(position, SeekOrigin.Begin); - - _readStream.Read(data, 0, length); - - if (_writeStream.Position != target) - _writeStream.Seek(target, SeekOrigin.Begin); - - _writeStream.Write(data, 0, length); - } - - public void WriteData(byte[] data, long position, int length) - { - if (_writeStream.Position != position) - _writeStream.Seek(position, SeekOrigin.Begin); - - _writeStream.Write(data, 0, length); - } - - public void Purge() - { - _writeStream.SetLength(0); - _indexStream.SetLength(0); - } - - public void CropData(long size) - { - _writeStream.SetLength(size); - } - - public override void Dispose() - { - _writeStream.Dispose(); - base.Dispose(); - } - } - - class Compacter : Writer - { - public Compacter(DbTableStorage table, Action finalizer) - : base(MoveFile(table), finalizer) - { - _readStream = _table.OpenRead(GetBackupName(_table), true); - } + class Compacter : Writer + { + public Compacter(DbTableStorage table, Action finalizer) + : base(MoveFile(table), finalizer) + { + _readStream = _table.OpenRead(GetBackupName(_table), true); + } - static DbTableStorage MoveFile(DbTableStorage table) - { - var backup = GetBackupName(table); + static DbTableStorage MoveFile(DbTableStorage table) + { + var backup = GetBackupName(table); - if (table._storage.FileExists(backup)) - table._storage.DeleteFile(backup); + if (table._storage.FileExists(backup)) + table._storage.DeleteFile(backup); - if (table._storage.FileExists(table._dataName)) - table._storage.MoveFile(table._dataName, backup); + if (table._storage.FileExists(table._dataName)) + table._storage.MoveFile(table._dataName, backup); - return table; - } + return table; + } - static string GetBackupName(DbTableStorage table) - { - return table._dataName + ".bak"; - } + static string GetBackupName(DbTableStorage table) + { + return table._dataName + ".bak"; + } - public override void Dispose() - { - base.Dispose(); + public override void Dispose() + { + base.Dispose(); - _table._storage.DeleteFile(GetBackupName(_table)); - } + _table._storage.DeleteFile(GetBackupName(_table)); + } + } } - } }