private long?TryFindSmallValue(LowLevelTransaction tx, FixedSizeTree freeSpaceTree, FixedSizeTree.IFixedSizeIterator it, int num) { do { var current = new StreamBitArray(it.CreateReaderForCurrent()); long?page; if (current.SetCount < num) { if (TryFindSmallValueMergingTwoSections(tx, freeSpaceTree, it.CurrentKey, num, current, out page)) { return(page); } continue; } if (TryFindContinuousRange(tx, freeSpaceTree, it, num, current, it.CurrentKey, out page)) { return(page); } //could not find a continuous so trying to merge if (TryFindSmallValueMergingTwoSections(tx, freeSpaceTree, it.CurrentKey, num, current, out page)) { return(page); } }while (it.MoveNext()); return(null); }
private long?TryFindSmallValue(Transaction tx, TreeIterator it, int num) { do { var stream = it.CreateReaderForCurrent(); { var current = new StreamBitArray(stream); var currentSectionId = it.CurrentKey.CreateReader().ReadBigEndianInt64(); long?page; if (current.SetCount < num) { if (TryFindSmallValueMergingTwoSections(tx, it, num, current, currentSectionId, out page)) { return(page); } continue; } if (TryFindContinuousRange(tx, it, num, current, currentSectionId, out page)) { return(page); } //could not find a continuous so trying to merge if (TryFindSmallValueMergingTwoSections(tx, it, num, current, currentSectionId, out page)) { return(page); } } } while (it.MoveNext()); return(null); }
public List <long> AllPages(Transaction tx) { if (tx.FreeSpaceRoot.State.EntriesCount == 0) { return(new List <long>()); } using (var it = tx.FreeSpaceRoot.Iterate()) { if (it.Seek(Slice.BeforeAllKeys) == false) { return(new List <long>()); } var freePages = new List <long>(); do { var stream = it.CreateReaderForCurrent(); var current = new StreamBitArray(stream); var currentSectionId = it.CurrentKey.CreateReader().ReadBigEndianInt64(); for (var i = 0; i < NumberOfPagesInSection; i++) { if (current.Get(i)) { freePages.Add(currentSectionId * NumberOfPagesInSection + i); } } } while (it.MoveNext()); return(freePages); } }
private static bool TryFindSmallValueMergingTwoSections(Transaction tx, TreeIterator it, int num, StreamBitArray current, long currentSectionId, out long?result) { result = -1; var currentRange = current.GetEndRangeCount(); if (currentRange == 0) { return(false); } var nextSectionId = currentSectionId + 1; var nextId = new Slice(EndianBitConverter.Big.GetBytes(nextSectionId)); var read = tx.State.FreeSpaceRoot.Read(nextId); if (read == null) { return(false); } var next = new StreamBitArray(read.Reader); var nextRange = num - currentRange; if (next.HasStartRangeCount(nextRange) == false) { return(false); } if (next.SetCount == nextRange) { tx.State.FreeSpaceRoot.Delete(nextId); } else { for (int i = 0; i < nextRange; i++) { next.Set(i, false); } tx.State.FreeSpaceRoot.Add(nextId, next.ToStream()); } if (current.SetCount == currentRange) { tx.State.FreeSpaceRoot.Delete(it.CurrentKey); } else { for (int i = 0; i < currentRange; i++) { current.Set(NumberOfPagesInSection - 1 - i, false); } tx.State.FreeSpaceRoot.Add(nextId, next.ToStream()); } result = currentSectionId * NumberOfPagesInSection + currentRange; return(true); }
private static bool TryFindSmallValueMergingTwoSections(LowLevelTransaction tx, FixedSizeTree freeSpacetree, long currentSectionId, int num, StreamBitArray current, out long?result) { result = -1; var currentEndRange = current.GetEndRangeCount(); if (currentEndRange == 0) { return(false); } var nextSectionId = currentSectionId + 1; var read = freeSpacetree.Read(nextSectionId); if (!read.HasValue) { return(false); } var next = new StreamBitArray(read.CreateReader()); var nextRange = num - currentEndRange; if (next.HasStartRangeCount(nextRange) == false) { return(false); } if (next.SetCount == nextRange) { freeSpacetree.Delete(nextSectionId); } else { for (int i = 0; i < nextRange; i++) { next.Set(i, false); } freeSpacetree.Add(nextSectionId, next.ToSlice(tx.Allocator)); } if (current.SetCount == currentEndRange) { freeSpacetree.Delete(currentSectionId); } else { for (int i = 0; i < currentEndRange; i++) { current.Set(NumberOfPagesInSection - 1 - i, false); } freeSpacetree.Add(currentSectionId, current.ToSlice(tx.Allocator)); } result = currentSectionId * NumberOfPagesInSection + (NumberOfPagesInSection - currentEndRange); return(true); }
private bool TryFindContinuousRange(LowLevelTransaction tx, FixedSizeTree freeSpaceTree, FixedSizeTree.IFixedSizeIterator it, int num, StreamBitArray current, long currentSectionId, out long?page) { page = -1; var start = -1; var count = 0; for (int i = 0; i < NumberOfPagesInSection; i++) { if (current.Get(i)) { if (start == -1) { start = i; } count++; if (count == num) { page = currentSectionId * NumberOfPagesInSection + start; break; } } else { start = -1; count = 0; } } if (count != num) { return(false); } if (current.SetCount == num) { freeSpaceTree.Delete(it.CurrentKey); } else { for (int i = 0; i < num; i++) { current.Set(i + start, false); } Slice val; using (current.ToSlice(tx.Allocator, out val)) freeSpaceTree.Add(it.CurrentKey, val); } return(true); }
private static bool TryFindSmallValueMergingTwoSections(Transaction tx, Slice currentSectionIdSlice, int num, StreamBitArray current, long currentSectionId, out long? result) { result = -1; var currentEndRange = current.GetEndRangeCount(); if (currentEndRange == 0) return false; var nextSectionId = currentSectionId + 1; var nextId = new Slice(EndianBitConverter.Big.GetBytes(nextSectionId)); var read = tx.State.FreeSpaceRoot.Read(nextId); if (read == null) return false; var next = new StreamBitArray(read.Reader); var nextRange = num - currentEndRange; if (next.HasStartRangeCount(nextRange) == false) return false; if (next.SetCount == nextRange) { tx.State.FreeSpaceRoot.Delete(nextId); } else { for (int i = 0; i < nextRange; i++) { next.Set(i, false); } tx.State.FreeSpaceRoot.Add(nextId, next.ToStream()); } if (current.SetCount == currentEndRange) { tx.State.FreeSpaceRoot.Delete(currentSectionIdSlice); } else { for (int i = 0; i < currentEndRange; i++) { current.Set(NumberOfPagesInSection - 1 - i, false); } tx.State.FreeSpaceRoot.Add(currentSectionIdSlice, current.ToStream()); } result = currentSectionId * NumberOfPagesInSection + (NumberOfPagesInSection - currentEndRange); return true; }
public List <long> AllPages(LowLevelTransaction tx) { var freeSpaceTree = GetFreeSpaceTree(tx); if (freeSpaceTree.NumberOfEntries == 0) { return(new List <long>()); } using (var it = freeSpaceTree.Iterate()) { if (it.Seek(0) == false) { return(new List <long>()); } var freePages = new List <long>(); do { var stream = it.CreateReaderForCurrent(); var current = new StreamBitArray(stream); var currentSectionId = it.CurrentKey; for (var i = 0; i < NumberOfPagesInSection; i++) { if (current.Get(i)) { freePages.Add(currentSectionId * NumberOfPagesInSection + i); } } } while (it.MoveNext()); return(freePages); } }
private long?TryFindLargeValue(Transaction tx, TreeIterator it, int num) { int numberOfNeededFullSections = num / NumberOfPagesInSection; int numberOfExtraBitsNeeded = num % NumberOfPagesInSection; int foundSections = 0; Slice startSection = null; long? startSectionId = null; var sections = new List <Slice>(); do { var stream = it.CreateReaderForCurrent(); { var current = new StreamBitArray(stream); var currentSectionId = it.CurrentKey.CreateReader().ReadBigEndianInt64(); //need to find full free pages if (current.SetCount < NumberOfPagesInSection) { ResetSections(ref foundSections, sections, ref startSection, ref startSectionId); continue; } //those sections are not following each other in the memory if (startSectionId != null && currentSectionId != startSectionId + foundSections) { ResetSections(ref foundSections, sections, ref startSection, ref startSectionId); } //set the first section of the sequence if (startSection == null) { startSection = it.CurrentKey; startSectionId = currentSectionId; } sections.Add(it.CurrentKey); foundSections++; if (foundSections != numberOfNeededFullSections) { continue; } //we found enough full sections now we need just a bit more if (numberOfExtraBitsNeeded == 0) { foreach (var section in sections) { tx.State.FreeSpaceRoot.Delete(section); } return(startSectionId * NumberOfPagesInSection); } var nextSectionId = currentSectionId + 1; var nextId = new Slice(EndianBitConverter.Big.GetBytes(nextSectionId)); var read = tx.State.FreeSpaceRoot.Read(nextId); if (read == null) { //not a following next section ResetSections(ref foundSections, sections, ref startSection, ref startSectionId); continue; } var next = new StreamBitArray(read.Reader); if (next.HasStartRangeCount(numberOfExtraBitsNeeded) == false) { //not enough start range count ResetSections(ref foundSections, sections, ref startSection, ref startSectionId); continue; } //mark selected bits to false if (next.SetCount == numberOfExtraBitsNeeded) { tx.State.FreeSpaceRoot.Delete(nextId); } else { for (int i = 0; i < numberOfExtraBitsNeeded; i++) { next.Set(i, false); } tx.State.FreeSpaceRoot.Add(nextId, next.ToStream()); } foreach (var section in sections) { tx.State.FreeSpaceRoot.Delete(section); } return(startSectionId * NumberOfPagesInSection); } } while (it.MoveNext()); return(null); }
private bool TryFindContinuousRange(Transaction tx, TreeIterator it, int num, StreamBitArray current, long currentSectionId, out long?page) { page = -1; var start = -1; var count = 0; for (int i = 0; i < NumberOfPagesInSection; i++) { if (current.Get(i)) { if (start == -1) { start = i; } count++; if (count == num) { page = currentSectionId * NumberOfPagesInSection + start; break; } } else { start = -1; count = 0; } } if (count != num) { return(false); } if (current.SetCount == num) { tx.State.FreeSpaceRoot.Delete(it.CurrentKey); } else { for (int i = 0; i < num; i++) { current.Set(i + start, false); } tx.State.FreeSpaceRoot.Add(it.CurrentKey, current.ToStream()); } return(true); }
private long? TryFindLargeValue(Transaction tx, TreeIterator it, int num) { int numberOfNeededFullSections = num / NumberOfPagesInSection; int numberOfExtraBitsNeeded = num % NumberOfPagesInSection; int foundSections = 0; MemorySlice startSection = null; long? startSectionId = null; var sections = new List<Slice>(); do { var stream = it.CreateReaderForCurrent(); { var current = new StreamBitArray(stream); var currentSectionId = it.CurrentKey.CreateReader().ReadBigEndianInt64(); //need to find full free pages if (current.SetCount < NumberOfPagesInSection) { ResetSections(ref foundSections, sections, ref startSection, ref startSectionId); continue; } //those sections are not following each other in the memory if (startSectionId != null && currentSectionId != startSectionId + foundSections) { ResetSections(ref foundSections, sections, ref startSection, ref startSectionId); } //set the first section of the sequence if (startSection == null) { startSection = it.CurrentKey; startSectionId = currentSectionId; } sections.Add(it.CurrentKey); foundSections++; if (foundSections != numberOfNeededFullSections) continue; //we found enough full sections now we need just a bit more if (numberOfExtraBitsNeeded == 0) { foreach (var section in sections) { tx.FreeSpaceRoot.Delete(section); } return startSectionId * NumberOfPagesInSection; } var nextSectionId = currentSectionId + 1; var nextId = new Slice(EndianBitConverter.Big.GetBytes(nextSectionId)); var read = tx.FreeSpaceRoot.Read(nextId); if (read == null) { //not a following next section ResetSections(ref foundSections, sections, ref startSection, ref startSectionId); continue; } var next = new StreamBitArray(read.Reader); if (next.HasStartRangeCount(numberOfExtraBitsNeeded) == false) { //not enough start range count ResetSections(ref foundSections, sections, ref startSection, ref startSectionId); continue; } //mark selected bits to false if (next.SetCount == numberOfExtraBitsNeeded) { tx.FreeSpaceRoot.Delete(nextId); } else { for (int i = 0; i < numberOfExtraBitsNeeded; i++) { next.Set(i, false); } tx.FreeSpaceRoot.Add(nextId, next.ToStream()); } foreach (var section in sections) { tx.FreeSpaceRoot.Delete(section); } return startSectionId * NumberOfPagesInSection; } } while (it.MoveNext()); return null; }
private bool TryFindContinuousRange(Transaction tx, TreeIterator it, int num, StreamBitArray current, long currentSectionId, out long? page) { page = -1; var start = -1; var count = 0; for (int i = 0; i < NumberOfPagesInSection; i++) { if (current.Get(i)) { if (start == -1) start = i; count++; if (count == num) { page = currentSectionId * NumberOfPagesInSection + start; break; } } else { start = -1; count = 0; } } if (count != num) return false; if (current.SetCount == num) { tx.FreeSpaceRoot.Delete(it.CurrentKey); } else { for (int i = 0; i < num; i++) { current.Set(i + start, false); } tx.FreeSpaceRoot.Add(it.CurrentKey, current.ToStream()); } return true; }
private long? TryFindSmallValue(Transaction tx, TreeIterator it, int num) { do { var stream = it.CreateReaderForCurrent(); { var current = new StreamBitArray(stream); var currentSectionId = it.CurrentKey.CreateReader().ReadBigEndianInt64(); long? page; if (current.SetCount < num) { if (TryFindSmallValueMergingTwoSections(tx, it.CurrentKey, num, current, currentSectionId, out page)) return page; continue; } if (TryFindContinuousRange(tx, it, num, current, currentSectionId, out page)) return page; //could not find a continuous so trying to merge if (TryFindSmallValueMergingTwoSections(tx, it.CurrentKey, num, current, currentSectionId, out page)) return page; } } while (it.MoveNext()); return null; }
private long?TryFindLargeValue(LowLevelTransaction tx, FixedSizeTree freeSpaceTree, FixedSizeTree.IFixedSizeIterator it, int num) { int numberOfNeededFullSections = num / NumberOfPagesInSection; int numberOfExtraBitsNeeded = num % NumberOfPagesInSection; var info = new FoundSectionsInfo(); do { var stream = it.CreateReaderForCurrent(); { var current = new StreamBitArray(stream); var currentSectionId = it.CurrentKey; //need to find full free pages if (current.SetCount < NumberOfPagesInSection) { info.Clear(); continue; } //those sections are not following each other in the memory if (info.StartSectionId != null && currentSectionId != info.StartSectionId + info.Sections.Count) { info.Clear(); } //set the first section of the sequence if (info.StartSection == -1) { info.StartSection = it.CurrentKey; info.StartSectionId = currentSectionId; } info.Sections.Add(it.CurrentKey); if (info.Sections.Count != numberOfNeededFullSections) { continue; } //we found enough full sections now we need just a bit more if (numberOfExtraBitsNeeded == 0) { foreach (var section in info.Sections) { freeSpaceTree.Delete(section); } return(info.StartSectionId * NumberOfPagesInSection); } StreamBitArray next; var nextSectionId = currentSectionId + 1; Slice read; using (freeSpaceTree.Read(nextSectionId, out read)) { if (!read.HasValue) { //not a following next section info.Clear(); continue; } next = new StreamBitArray(read.CreateReader()); } if (next.HasStartRangeCount(numberOfExtraBitsNeeded) == false) { //not enough start range count info.Clear(); continue; } //mark selected bits to false if (next.SetCount == numberOfExtraBitsNeeded) { freeSpaceTree.Delete(nextSectionId); } else { for (int i = 0; i < numberOfExtraBitsNeeded; i++) { next.Set(i, false); } Slice val; using (next.ToSlice(tx.Allocator, out val)) freeSpaceTree.Add(nextSectionId, val); } foreach (var section in info.Sections) { freeSpaceTree.Delete(section); } return(info.StartSectionId * NumberOfPagesInSection); } } while (it.MoveNext()); return(null); }