public void AfmReturnsRightNumberOfJObjects() { _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(10000).ToList(); foreach (var entity in addEntities) entity.Id = _seed.Increment(); IDictionary<int, long> returnSegments = null; 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>()); tranny.MarkComplete(); }); using (var tLock1 = manager.BeginTransaction()) { addEntities.ForEach(delegate(MockClassA entity) { tLock1.Transaction.Enlist(Action.Create, entity.Id, entity); }); tLock1.Transaction.Commit(); Assert.AreEqual(10000, afm.Length); } foreach (var group in afm.AsEnumerable()) { var match = group.Where(i => i.SelectToken("Id").Value<int>() > 9999).ToList(); if (match == null || !match.Any()) continue; var result = match.First(r => r.Value<int>("Id") == 10000).ToObject<MockClassC>(); Assert.IsNotNull(result); Assert.AreEqual(10000, result.Id); break; } } } }
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 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 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); } } }