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 AtomicFileManagerReturnsPagedStream()
        {
            _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>();

                afm.Rebuilt += new Rebuild<MockClassA>(delegate(Guid transactionId, int newStride, long newLength, int newSeedStride)
                {
                    afm.SaveCore<int>();
                });

                var segs = AtomicFileManagerHelper.SaveSegments(afm, addEntities.ToDictionary(e => e.Id));

                afm.SaveCore<int>();

                var s = afm.GetPageStream(1);

                Assert.IsNotNull(s);
                Assert.GreaterOrEqual(s.Length, 1441792);
                Assert.AreEqual(8, afm.AsStreaming().Count());
            }
        }
        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 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 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 AfmInitializes()
        {
            _testName = MethodInfo.GetCurrentMethod().Name.GetHashCode().ToString();
            Cleanup();

            var formatter = TestResourceFactory.CreateJsonFormatterWithoutArrayFormatting();
            var core = new FileCore<int, long>() { IdSeed = new Seed32(0), SegmentSeed = new Seed64(), MinimumCoreStride = 512 };

            using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", new FileCore<int, long>(), formatter))
            {
                afm.Load<int>();
            }

            using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", formatter))
            {
                afm.Load<int>();
                Assert.AreEqual(512, afm.Stride);
                Assert.AreEqual(10240, afm.CorePosition);
            }
        }
        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);
            }
        }
Beispiel #8
0
        public void IndexClosesWithCorrectLength()
        {
            _testName = MethodInfo.GetCurrentMethod().Name.GetHashCode().ToString();
            Cleanup();

            var formatter = TestResourceFactory.CreateJsonFormatterWithoutArrayFormatting();
            var core = new FileCore<string, long>() { IdSeed = new SeedString(2048), SegmentSeed = new Seed64(), Stride = 512 };

            var objs = TestResourceFactory.GetMockClassAObjects(1000).ToDictionary(d => d.Name);
            var additions = TestResourceFactory.GetMockClassAObjects(2).ToDictionary(d => d.Name);

            IDictionary<string, long> segs = null;

            using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, formatter))
            {
                using (var index = new Index<string, MockClassA, long>(_testName + ".index", "Name", true, 8, new BinConverterString(2048), new BinConverter64(), new RowSynchronizer<long>(new BinConverter64()), new RowSynchronizer<int>(new BinConverter32())))
                {
                    afm.Load<string>();

                    index.Load();
                    index.Register(afm);

                    segs = AtomicFileManagerHelper.SaveSegments(afm, objs);

                    Assert.AreEqual(1000, index.Length);
                }
            }

            using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, formatter))
            {
                using (var index = new Index<string, MockClassA, long>(_testName + ".index", "Name", true, 8, new BinConverterString(2048), new BinConverter64(), new RowSynchronizer<long>(new BinConverter64()), new RowSynchronizer<int>(new BinConverter32())))
                {
                    afm.Load<string>();

                    index.Load();

                    Assert.AreEqual(1000, index.Length);

                    index.Register(afm);

                    Assert.AreEqual(1000, index.Length);

                    var idx = DynamicMemberManager.GetManager(index);
                    var pt = DynamicMemberManager.GetManager(idx._pTree);

                    Assert.AreEqual(3, pt._cache.Count);
                    Assert.AreEqual(400, pt._cache[0].Count);

                    segs = AtomicFileManagerHelper.SaveSegments(afm, additions);
                }
            }

            using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, formatter))
            {
                using (var index = new Index<string, MockClassA, long>(_testName + ".index", "Name", true, 8, new BinConverterString(2048), new BinConverter64(), new RowSynchronizer<long>(new BinConverter64()), new RowSynchronizer<int>(new BinConverter32())))
                {
                    afm.Load<string>();

                    index.Load();

                    Assert.AreEqual(1002, index.Length);

                    index.Register(afm);

                    Assert.AreEqual(1002, index.Length);

                    var seg = index.FetchSegment(additions.First().Key);

                    Assert.IsNotNull(seg);
                }
            }
        }
Beispiel #9
0
        public void IndexReorganizes()
        {
            _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 objs = TestResourceFactory.GetMockClassAObjects(100).ToDictionary(d => d.Id = core.IdSeed.Increment());

            IDictionary<int, long> segs = null;

            using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, formatter))
            {
                using (var index = new Index<int, MockClassA, long>(_testName + ".index", "Id", true, 8, new BinConverter32(), new BinConverter64(), new RowSynchronizer<long>(new BinConverter64()), new RowSynchronizer<int>(new BinConverter32())))
                {
                    afm.Load<int>();

                    index.Load();

                    segs = AtomicFileManagerHelper.SaveSegments(afm, objs);

                    //should trigger re-org.
                    index.Register(afm);

                    Assert.AreEqual(objs.Count, segs.Count);

                    afm.SaveCore();

                    long seg;
                    var f = index.FetchIndex(segs[objs.First().Key], out seg);
                    Assert.AreEqual(objs.First().Key, f);

                    long[] segList;
                    var all = index.FetchIndexes(segs.Values.ToArray(), out segList);
                    Assert.AreEqual(objs.Count, all.Count());

                    var many = index.FetchIndexes(segs[objs.First().Key], out segList);
                    Assert.AreEqual(1, many.Count());
                }
            }

            using (var afm = new AtomicFileManager<MockClassA>(_testName + ".database", core, formatter))
            {
                using (var index = new Index<int, MockClassA, long>(_testName + ".index", "Id", true))
                {
                    afm.Load<int>();

                    index.Load();
                    index.Register(afm);

                    var f = index.FetchSegment(objs.First().Key);
                    Assert.AreEqual(segs[objs.First().Key], f);

                    var all = index.FetchSegments(objs.First().Key, objs.Last().Key);
                    Assert.AreEqual(objs.Count, all.Count());

                    var many = index.FetchSegments(new int[] { objs.First().Key, objs.Last().Key });
                    Assert.AreEqual(2, many.Count());
                }
            }
        }
        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);
                }
            }
        }