public void AfmCommitsComplexTransaction() { _testName = MethodInfo.GetCurrentMethod().Name.GetHashCode().ToString(); Cleanup(); var formatter = new BSONFormatter(); var core = new FileCore<int, long>() { IdSeed = new Seed32(999), SegmentSeed = new Seed64(), Stride = 32 }; var addEntities = TestResourceFactory.GetMockClassAObjects(25).ToList(); foreach (var entity in addEntities) entity.Id = core.IdSeed.Increment(); var updateEntities = new List<MockClassC>(); IDictionary<int, long> returnSegments = null; using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, formatter)) { afm.Load<int>(); using (var manager = new TransactionManager<int, MockClassA> (new MockTransactionFactory<int, MockClassA>() , new TransactionSynchronizer<int, MockClassA>())) { afm.Rebuilt += new Rebuild<MockClassA>(delegate(Guid transactionId, int newStride, long newLength, int newSeedStride) { var c = (IFileCore<int, long>)afm.Core; c.Stride = newStride; c.MinimumCoreStride = newSeedStride; afm.SaveCore<int>(); }); manager.TransactionCommitted += new TransactionCommit<int, MockClassA>( delegate(ITransaction<int, MockClassA> tranny) { returnSegments = afm.CommitTransaction(tranny, new Dictionary<int, long>()); tranny.MarkComplete(); }); using (var tLock = manager.BeginTransaction()) { addEntities.ForEach(delegate(MockClassA entity) { tLock.Transaction.Enlist(Action.Create, entity.Id, entity); }); tLock.Transaction.Commit(); Assert.AreEqual(25, afm.Length); } } } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", formatter)) { afm.Load<int>(); Assert.AreEqual(25, afm.Length); using (var manager = new TransactionManager<int, MockClassA> (new MockTransactionFactory<int, MockClassA>() , new TransactionSynchronizer<int, MockClassA>())) { afm.Rebuilt += new Rebuild<MockClassA>(delegate(Guid transactionId, int newStride, long newLength, int newSeedStride) { var c = (IFileCore<int, long>)afm.Core; c.Stride = newStride; c.MinimumCoreStride = newSeedStride; afm.SaveCore<int>(); }); manager.TransactionCommitted += new TransactionCommit<int, MockClassA>( delegate(ITransaction<int, MockClassA> tranny) { returnSegments = afm.CommitTransaction(tranny, returnSegments); tranny.MarkComplete(); }); using (var tLock = manager.BeginTransaction()) { foreach (var kvp in returnSegments) updateEntities.Add(afm.LoadSegmentFrom(kvp.Value) as MockClassC); updateEntities.ForEach(u => u.Name = (u.Location.X + u.Location.Y).ToString() + u.Name); updateEntities.ForEach(u => tLock.Transaction.Enlist(Action.Update, u.Id, u)); var insert = TestResourceFactory.CreateRandom().WithName("numb nugget") as MockClassC; insert.Id = core.IdSeed.Increment(); updateEntities.Add(insert); tLock.Transaction.Enlist(Action.Create, insert.Id, insert); tLock.Transaction.Commit(); Assert.AreEqual(26, afm.Length); } } } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", formatter)) { afm.Load<int>(); Assert.LessOrEqual(461, afm.Stride); Assert.AreEqual(10240, afm.CorePosition); foreach (var entity in updateEntities) { var obj = afm.LoadSegmentFrom(returnSegments[entity.Id]) as MockClassC; Assert.IsNotNull(obj); Assert.AreEqual(entity.Id, obj.Id); Assert.AreEqual(entity.Name, obj.Name); Assert.AreEqual(entity.GetSomeCheckSum, obj.GetSomeCheckSum); Assert.AreEqual(entity.Location.X, obj.Location.X); Assert.AreEqual(entity.Location.Y, obj.Location.Y); Assert.AreEqual(entity.Location.Z, obj.Location.Z); Assert.AreEqual(entity.Location.W, obj.Location.W); Assert.AreEqual(entity.ReferenceCode, obj.ReferenceCode); Assert.AreEqual(entity.ReplicationID, obj.ReplicationID); } } }
public void AfmSavesNewObjects() { _testName = MethodInfo.GetCurrentMethod().Name.GetHashCode().ToString(); var formatter = TestResourceFactory.CreateJsonFormatterWithoutArrayFormatting(); var core = new FileCore<int, long>() { IdSeed = new Seed32(999), SegmentSeed = new Seed64(), MinimumCoreStride = 512 }; var entity = TestResourceFactory.CreateRandom() as MockClassC; long seg = -1; using (var fLock = new ManagedFileLock(_testName)) { Cleanup(); using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core)) { afm.Load<int>(); entity.Id = core.IdSeed.Increment(); afm.Rebuilt += new Rebuild<MockClassA>(delegate(Guid transactionId, int newStride, long newLength, int newSeedStride) { afm.SaveCore<int>(); }); seg = AtomicFileManagerHelper.SaveSegment(afm, entity, entity.Id); afm.SaveCore<int>(); } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database")) { afm.Load<int>(); Assert.AreEqual(512, afm.Stride); Assert.AreEqual(1024, afm.CorePosition); var obj = afm.LoadSegmentFrom(seg) as MockClassC; Assert.IsNotNull(obj); Assert.AreEqual(entity.Id, obj.Id); Assert.AreEqual(entity.Name, obj.Name); Assert.AreEqual(entity.GetSomeCheckSum, obj.GetSomeCheckSum); Assert.AreEqual(entity.Location.X, obj.Location.X); Assert.AreEqual(entity.Location.Y, obj.Location.Y); Assert.AreEqual(entity.Location.Z, obj.Location.Z); Assert.AreEqual(entity.Location.W, obj.Location.W); Assert.AreEqual(entity.ReferenceCode, obj.ReferenceCode); Assert.AreEqual(entity.ReplicationID, obj.ReplicationID); } } }
public void AfmUpdatesAndDeletesExistingObjects() { _testName = MethodInfo.GetCurrentMethod().Name.GetHashCode().ToString(); var formatter = TestResourceFactory.CreateJsonFormatterWithoutArrayFormatting(); var core = new FileCore<int, long>() { IdSeed = new Seed32(999), SegmentSeed = new Seed64(), MinimumCoreStride = 512 }; var entity1 = TestResourceFactory.CreateRandom() as MockClassC; var entity2 = TestResourceFactory.CreateRandom() as MockClassC; long seg = -1; using (var fLock = new ManagedFileLock(_testName)) { Cleanup(); using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, formatter)) { afm.Load<int>(); seg = AtomicFileManagerHelper.SaveSegment(afm, entity1, entity1.Id); } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", formatter)) { afm.Load<int>(); AtomicFileManagerHelper.SaveSegment(afm, entity2, entity2.Id, seg); } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", formatter)) { afm.Load<int>(); Assert.Less(512, afm.Stride); Assert.Greater(1024, afm.CorePosition); var obj = afm.LoadSegmentFrom(seg) as MockClassC; Assert.IsNotNull(obj); Assert.AreEqual(entity2.Id, obj.Id); Assert.AreEqual(entity2.Name, obj.Name); Assert.AreEqual(entity2.GetSomeCheckSum, obj.GetSomeCheckSum); Assert.AreEqual(entity2.Location.X, obj.Location.X); Assert.AreEqual(entity2.Location.Y, obj.Location.Y); Assert.AreEqual(entity2.Location.Z, obj.Location.Z); Assert.AreEqual(entity2.Location.W, obj.Location.W); Assert.AreEqual(entity2.ReferenceCode, obj.ReferenceCode); Assert.AreEqual(entity2.ReplicationID, obj.ReplicationID); AtomicFileManagerHelper.DeleteSegment(afm, obj.Id, seg); obj = afm.LoadSegmentFrom(seg) as MockClassC; Assert.IsNull(obj); } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", formatter)) { afm.Load<int>(); var obj = afm.LoadSegmentFrom(seg) as MockClassC; Assert.IsNull(obj); } } }
public void AfmCommitsSimpleTransaction() { _testName = MethodInfo.GetCurrentMethod().Name.GetHashCode().ToString(); Cleanup(); var formatter = TestResourceFactory.CreateJsonFormatterWithoutArrayFormatting(); var core = new FileCore<int, long>() { IdSeed = new Seed32(999), SegmentSeed = new Seed64(), Stride = 512 }; var entity1 = TestResourceFactory.CreateRandom() as MockClassC; MockClassC entity2; long seg = -1; using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, formatter)) { afm.Load<int>(); entity1.Id = 1001; seg = AtomicFileManagerHelper.SaveSegment(afm, entity1, entity1.Id); } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", formatter)) { afm.Load<int>(); entity2 = entity1.WithName("No Name Joe") as MockClassC; AtomicFileManagerHelper.SaveSegment(afm, entity2, entity2.Id, seg); } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", formatter)) { afm.Load<int>(); Assert.Less(512, afm.Stride); Assert.AreEqual(10240, afm.CorePosition); var obj = afm.LoadSegmentFrom(seg) as MockClassC; Assert.IsNotNull(obj); Assert.AreEqual(entity2.Id, obj.Id); Assert.AreEqual(entity2.Name, obj.Name); Assert.AreEqual(entity2.GetSomeCheckSum, obj.GetSomeCheckSum); Assert.AreEqual(entity2.Location.X, obj.Location.X); Assert.AreEqual(entity2.Location.Y, obj.Location.Y); Assert.AreEqual(entity2.Location.Z, obj.Location.Z); Assert.AreEqual(entity2.Location.W, obj.Location.W); Assert.AreEqual(entity2.ReferenceCode, obj.ReferenceCode); Assert.AreEqual(entity2.ReplicationID, obj.ReplicationID); } }
public void AfmRebuildsOnFailedTransaction() { _testName = MethodInfo.GetCurrentMethod().Name.GetHashCode().ToString(); var formatter = new BSONFormatter(); var core = new FileCore<int, long>() { IdSeed = new Seed32(999), SegmentSeed = new Seed64(), MinimumCoreStride = 512 }; var entity = TestResourceFactory.CreateRandom() as MockClassC; var largeEntity = TestResourceFactory.CreateRandom().WithName(new String('a', 2000)) as MockClassC; IDictionary<int, long> returnSegments = null; using (var fLock = new ManagedFileLock(_testName)) { Cleanup(); using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, formatter)) { afm.Load<int>(); using (var manager = new TransactionManager<int, MockClassA> (new MockTransactionFactory<int, MockClassA>() , new TransactionSynchronizer<int, MockClassA>())) { manager.TransactionCommitted += new TransactionCommit<int, MockClassA>( delegate(ITransaction<int, MockClassA> tranny) { returnSegments = afm.CommitTransaction(tranny, new Dictionary<int, long>()); while (afm.FileFlushQueueActive) Thread.Sleep(100); tranny.MarkComplete(); afm.SaveCore<int>(); }); using (var tLock = manager.BeginTransaction()) { tLock.Transaction.Enlist(Action.Create, entity.Id, entity); tLock.Transaction.Commit(); } } } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", formatter)) { afm.Load<int>(); using (var manager = new TransactionManager<int, MockClassA> (new MockTransactionFactory<int, MockClassA>() , new TransactionSynchronizer<int, MockClassA>())) { manager.TransactionCommitted += new TransactionCommit<int, MockClassA>( delegate(ITransaction<int, MockClassA> tranny) { returnSegments = afm.CommitTransaction(tranny, returnSegments); while (afm.FileFlushQueueActive) Thread.Sleep(100); tranny.MarkComplete(); afm.SaveCore<int>(); }); using (var tLock = manager.BeginTransaction()) { tLock.Transaction.Enlist(Action.Update, largeEntity.Id, largeEntity); tLock.Transaction.Commit(); } } } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", formatter)) { afm.Load<int>(); Assert.Greater(afm.Stride, 2200); Assert.AreEqual(1024, afm.CorePosition); var obj = afm.LoadSegmentFrom(returnSegments.First().Value) as MockClassC; Assert.IsNotNull(obj); Assert.AreEqual(largeEntity.Id, obj.Id); Assert.AreEqual(largeEntity.Name, obj.Name); Assert.AreEqual(largeEntity.GetSomeCheckSum, obj.GetSomeCheckSum); Assert.AreEqual(largeEntity.Location.X, obj.Location.X); Assert.AreEqual(largeEntity.Location.Y, obj.Location.Y); Assert.AreEqual(largeEntity.Location.Z, obj.Location.Z); Assert.AreEqual(largeEntity.Location.W, obj.Location.W); Assert.AreEqual(largeEntity.ReferenceCode, obj.ReferenceCode); Assert.AreEqual(largeEntity.ReplicationID, obj.ReplicationID); } } }
public void AfmReorganizesWithCorrectNumberOfRows() { _testName = MethodInfo.GetCurrentMethod().Name.GetHashCode().ToString(); var formatter = new BSONFormatter(); var core = new FileCore<int, long>() { IdSeed = new Seed32(999), SegmentSeed = new Seed64(), MinimumCoreStride = 512, InitialDbSize = 10240 }; var addEntities = TestResourceFactory.GetMockClassAObjects(10000).ToList(); foreach (var entity in addEntities) entity.Id = core.IdSeed.Increment(); addEntities.Reverse(); using (var fLock = new ManagedFileLock(_testName)) { Cleanup(); using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", 4096, 20000, 4096, core, formatter, new RowSynchronizer<long>(new BinConverter64()))) { afm.Load<int>(); afm.Rebuilt += new Rebuild<MockClassA>(delegate(Guid transactionId, int newStride, long newLength, int newSeedStride) { afm.SaveCore<int>(); }); AtomicFileManagerHelper.SaveSegments(afm, addEntities.ToDictionary(e => e.Id)); } addEntities.Reverse(); var seg = 1; using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", 4096, 20000, 4096, formatter, new RowSynchronizer<long>(new BinConverter64()))) { afm.Load<int>(); Assert.AreNotEqual(1, afm.LoadSegmentFrom(seg).Id); afm.Reorganized += new Reorganized<MockClassA>(delegate(int recordsWritten) { afm.SaveCore<int>(); }); afm.Reorganize<int>(new BinConverter32(), j => j.Value<int>("Id")); } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", 4096, 20000, 4096, core, formatter, new RowSynchronizer<long>(new BinConverter64()))) { afm.Load<int>(); foreach (var entity in addEntities) { Assert.AreEqual(entity.Id, afm.LoadSegmentFrom(seg).Id, "Id {0} was not found in the right order, Id {1} was found instead.", entity.Id, afm.LoadSegmentFrom(seg).Id); seg++; } } } }
public void AfmRebuildsWithNewStride() { _testName = MethodInfo.GetCurrentMethod().Name.GetHashCode().ToString(); Cleanup(); var formatter = new JSONFormatter(); var core = new FileCore<string, long>() { IdSeed = new SeedString(), SegmentSeed = new Seed64(), MinimumCoreStride = 512 }; var entity = TestResourceFactory.CreateRandom() as MockClassC; var largeEntity = TestResourceFactory.CreateRandom().WithName(new String('a', 2000)) as MockClassC; long seg = 0; using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, new JSONFormatter())) { afm.Load<string>(); afm.Rebuilt += new Rebuild<MockClassA>(delegate(Guid transactionId, int newStride, long newLength, int newSeedStride) { afm.SaveCore<string>(); }); seg = AtomicFileManagerHelper.SaveSegment(afm, entity, entity.Name); afm.SaveCore(); } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, new JSONFormatter())) { afm.Load<string>(); afm.Rebuilt += new Rebuild<MockClassA>(delegate(Guid transactionId, int newStride, long newLength, int newSeedStride) { afm.SaveCore<string>(); }); seg = AtomicFileManagerHelper.SaveSegment(afm, largeEntity, largeEntity.Name); } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, formatter)) { afm.Load<string>(); Assert.Greater(afm.Stride, 500); Assert.AreEqual(512, afm.Core.MinimumCoreStride); var obj = afm.LoadSegmentFrom(seg) as MockClassC; Assert.IsNotNull(obj); Assert.AreEqual(largeEntity.Id, obj.Id); Assert.AreEqual(largeEntity.Name, obj.Name); Assert.AreEqual(largeEntity.GetSomeCheckSum, obj.GetSomeCheckSum); Assert.AreEqual(largeEntity.Location.X, obj.Location.X); Assert.AreEqual(largeEntity.Location.Y, obj.Location.Y); Assert.AreEqual(largeEntity.Location.Z, obj.Location.Z); Assert.AreEqual(largeEntity.Location.W, obj.Location.W); Assert.AreEqual(largeEntity.ReferenceCode, obj.ReferenceCode); Assert.AreEqual(largeEntity.ReplicationID, obj.ReplicationID); } }
public void AfmRebuildsWithNewSeedSize() { _testName = MethodInfo.GetCurrentMethod().Name.GetHashCode().ToString(); Cleanup(); var formatter = new BSONFormatter(); var core = new FileCore<int, long>() { IdSeed = new Seed32(999), SegmentSeed = new Seed64(), MinimumCoreStride = 512 }; var addEntities = TestResourceFactory.GetMockClassAObjects(20480).ToList(); foreach (var entity in addEntities) entity.Id = core.IdSeed.Increment(); var updateEntities = new List<MockClassC>(); IDictionary<int, long> returnSegments = null; IDictionary<int, long> deletedSegments = new Dictionary<int, long>(); using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core)) { afm.Load<int>(); using (var manager = new TransactionManager<int, MockClassA> (new MockTransactionFactory<int, MockClassA>() , new TransactionSynchronizer<int, MockClassA>())) { manager.TransactionCommitted += new TransactionCommit<int, MockClassA>( delegate(ITransaction<int, MockClassA> tranny) { returnSegments = afm.CommitTransaction(tranny, new Dictionary<int, long>()); while (afm.FileFlushQueueActive) Thread.Sleep(100); tranny.MarkComplete(); afm.SaveCore<int>(); }); using (var tLock = manager.BeginTransaction()) { addEntities.ForEach(delegate(MockClassA entity) { tLock.Transaction.Enlist(Action.Create, entity.Id, entity); }); Assert.AreEqual(20480, tLock.Transaction.EnlistCount); tLock.Transaction.Commit(); Assert.AreEqual(20480, afm.Length); } } } using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core)) { afm.Load<int>(); Assert.AreEqual(20480, afm.Length); using (var manager = new TransactionManager<int, MockClassA> (new MockTransactionFactory<int, MockClassA>() , new TransactionSynchronizer<int, MockClassA>())) { manager.TransactionCommitted += new TransactionCommit<int, MockClassA>( delegate(ITransaction<int, MockClassA> tranny) { returnSegments = afm.CommitTransaction(tranny, returnSegments); while (afm.FileFlushQueueActive) Thread.Sleep(100); tranny.MarkComplete(); afm.SaveCore<int>(); core.MinimumCoreStride = (int)formatter.FormatObjStream(core).Length; }); using (var tLock = manager.BeginTransaction()) { deletedSegments = returnSegments.Take(9000).ToDictionary(k => k.Key, k => k.Value); foreach (var kvp in deletedSegments) updateEntities.Add(afm.LoadSegmentFrom(kvp.Value) as MockClassC); updateEntities.ForEach(u => tLock.Transaction.Enlist(Action.Delete, u.Id, u)); tLock.Transaction.Commit(); afm.SaveCore<int>(); } Assert.AreEqual(512, afm.Stride); //Deleting items from the database adds those idsToDelete to the segmentSeed'aqn open Ids list, increasing it'aqn size. It'aqn an easy way to check for segmentSeed rebuilding. Assert.Greater(afm.Core.MinimumCoreStride, 23000); } } }