Beispiel #1
0
        public void ShouldReturnValidIdsOfEntriesInSectionThatAreReadable()
        {
            long pageNumber;

            using (var tx = Env.WriteTransaction())
            {
                var section = ActiveRawDataSmallSection.Create(tx.LowLevelTransaction, "test", (byte)TableType.None);
                pageNumber = section.PageNumber;
                tx.Commit();
            }

            long idWhichIsGoingToBeDeleted1;
            long idWhichIsGoingToBeDeleted2;
            long existingId;

            using (var tx = Env.WriteTransaction())
            {
                var section = new ActiveRawDataSmallSection(tx.LowLevelTransaction, pageNumber);

                Assert.True(section.TryAllocate(2000, out idWhichIsGoingToBeDeleted1));
                WriteValue(section, idWhichIsGoingToBeDeleted1, 1.ToString("0000000000000"));
                Assert.True(section.TryAllocate(2000, out idWhichIsGoingToBeDeleted2));
                WriteValue(section, idWhichIsGoingToBeDeleted2, 2.ToString("0000000000000"));

                Assert.True(section.TryAllocate(2000, out existingId));
                WriteValue(section, existingId, 3.ToString("0000000000000"));
                tx.Commit();
            }

            using (var tx = Env.WriteTransaction())
            {
                var section = new ActiveRawDataSmallSection(tx.LowLevelTransaction, pageNumber);

                section.Free(idWhichIsGoingToBeDeleted1);
                section.Free(idWhichIsGoingToBeDeleted2);
                tx.Commit();
            }

            using (var tx = Env.WriteTransaction())
            {
                var section = new ActiveRawDataSmallSection(tx.LowLevelTransaction, pageNumber);
                var ids     = section.GetAllIdsInSectionContaining(existingId);

                Assert.Equal(1, ids.Count);
                Assert.Equal(existingId, ids[0]);

                AssertValueMatches(section, existingId, 3.ToString("0000000000000"));
            }
        }
Beispiel #2
0
        public void CanAllocateEnoughToFillEntireSection()
        {
            long pageNumber;

            using (var tx = Env.WriteTransaction())
            {
                var section = ActiveRawDataSmallSection.Create(tx.LowLevelTransaction, "test", (byte)TableType.None);
                pageNumber = section.PageNumber;
                tx.Commit();
            }

            using (var tx = Env.WriteTransaction())
            {
                var section = new ActiveRawDataSmallSection(tx.LowLevelTransaction, pageNumber);
                section.DataMoved += (previousId, newId, data, size) => { };
                int allocationSize = 1020;

                long id;

                var list = new List <long>();

                while (section.TryAllocate(allocationSize, out id))
                {
                    list.Add(id);
                }

                Assert.False(section.TryAllocate(allocationSize, out id));

                var idToFree = list[list.Count / 2];

                section.Free(idToFree);

                Assert.True(section.TryAllocate(allocationSize, out id));
            }
        }
Beispiel #3
0
        public void WhatShouldWeDoHere()
        {
            long pageNumber;

            using (var tx = Env.WriteTransaction())
            {
                var section = ActiveRawDataSmallSection.Create(tx.LowLevelTransaction, "test", (byte)TableType.None);
                pageNumber = section.PageNumber;
                tx.Commit();
            }

            using (var tx = Env.WriteTransaction())
            {
                var section = new ActiveRawDataSmallSection(tx.LowLevelTransaction, pageNumber);

                Assert.Throws <InvalidOperationException>(() => section.Free(0));
            }
        }
Beispiel #4
0
        public void Delete(long id)
        {
            int size;
            var ptr = DirectRead(id, out size);

            if (ptr == null)
            {
                return;
            }

            var stats = (TableSchemaStats *)_tableTree.DirectAdd(TableSchema.Stats, sizeof(TableSchemaStats));

            NumberOfEntries--;
            stats->NumberOfEntries = NumberOfEntries;

            DeleteValueFromIndex(id, new TableValueReader(ptr, size));

            var largeValue = (id % _pageSize) == 0;

            if (largeValue)
            {
                var page          = _tx.LowLevelTransaction.GetPage(id / _pageSize);
                var numberOfPages = _tx.LowLevelTransaction.DataPager.GetNumberOfOverflowPages(page.OverflowSize);
                for (int i = 0; i < numberOfPages; i++)
                {
                    _tx.LowLevelTransaction.FreePage(page.PageNumber + i);
                }
                return;
            }

            var density = ActiveDataSmallSection.Free(id);

            if (ActiveDataSmallSection.Contains(id) || density > 0.5)
            {
                return;
            }

            var sectionPageNumber = ActiveDataSmallSection.GetSectionPageNumber(id);

            if (density > 0.15)
            {
                ActiveCandidateSection.Add(sectionPageNumber);
                return;
            }

            // move all the data to the current active section (maybe creating a new one
            // if this is busy)

            // if this is in the active candidate list, remove it so it cannot be reused if the current
            // active is full and need a new one
            ActiveCandidateSection.Delete(sectionPageNumber);

            var idsInSection = ActiveDataSmallSection.GetAllIdsInSectionContaining(id);

            foreach (var idToMove in idsInSection)
            {
                int itemSize;
                var pos   = ActiveDataSmallSection.DirectRead(idToMove, out itemSize);
                var newId = AllocateFromSmallActiveSection(itemSize);

                OnDataMoved(idToMove, newId, pos, itemSize);

                byte *writePos;
                if (ActiveDataSmallSection.TryWriteDirect(newId, itemSize, out writePos) == false)
                {
                    throw new InvalidDataException($"Cannot write to newly allocated size in {Name} during delete");
                }

                Memory.Copy(writePos, pos, itemSize);
            }

            ActiveDataSmallSection.DeleteSection(sectionPageNumber);
        }