예제 #1
0
        void RemoveTransactions(BinarySearchRange range)
        {
            if (range == BinarySearchRange.invalid)
            {
                return;
            }

            var totalTransactions = GetTotalReadableTransactions(m_Fs);
            var nbRemoved         = range.endOffset - range.startOffset;
            var newSize           = m_HeaderSize + (totalTransactions - nbRemoved) * transactionSize;

            var transactionsToShift = totalTransactions - range.endOffset;

            if (transactionsToShift > 0)
            {
                m_Fs.Seek(range.endOffset * transactionSize + m_HeaderSize, SeekOrigin.Begin);
                var readTransactions = new Transaction[transactionsToShift];
                for (var i = 0; i < transactionsToShift; ++i)
                {
                    readTransactions[i] = Transaction.FromBinary(m_Br);
                }
                m_Fs.Seek(range.startOffset * transactionSize + m_HeaderSize, SeekOrigin.Begin);
                for (var i = 0; i < transactionsToShift; ++i)
                {
                    readTransactions[i].ToBinary(m_Bw);
                }
            }
            m_Fs.SetLength(newSize);
            m_Fs.Flush(true);
        }
예제 #2
0
 void InvalidateRange(BinarySearchRange binarySearchRange)
 {
     using (LockWrite())
     {
         for (var i = binarySearchRange.startOffset; i < binarySearchRange.endOffset; ++i)
         {
             var record    = m_StoreData[(int)i];
             var newRecord = new PropertyDatabaseRecord(record.recordKey, record.recordValue, false);
             m_StoreData[(int)i] = newRecord;
         }
     }
 }
예제 #3
0
        public static bool Find(IBinarySearchRangeData <PropertyDatabaseRecordKey> store, PropertyDatabaseRecordKey recordKey, out long index)
        {
            if (store.length == 0)
            {
                index = 0;
                return(false);
            }

            var searchRange = new BinarySearchRange()
            {
                startOffset = 0, endOffset = store.length, halfOffset = store.length / 2
            };

            while (true)
            {
                index = searchRange.halfOffset;
                var currentRecordKey = store[index];

                if (recordKey == currentRecordKey)
                {
                    index = searchRange.halfOffset;
                    return(true);
                }

                if (recordKey < currentRecordKey)
                {
                    searchRange.endOffset  = searchRange.halfOffset;
                    searchRange.halfOffset = searchRange.startOffset + (searchRange.endOffset - searchRange.startOffset) / 2;

                    if (searchRange.halfOffset == searchRange.endOffset)
                    {
                        break;
                    }
                }
                else
                {
                    searchRange.startOffset = searchRange.halfOffset;
                    searchRange.halfOffset  = searchRange.startOffset + (searchRange.endOffset - searchRange.startOffset) / 2;

                    if (searchRange.halfOffset == searchRange.startOffset)
                    {
                        ++index;
                        break;
                    }
                }
            }

            return(false);
        }
예제 #4
0
 void InvalidateMaskRange(BinarySearchRange binarySearchRange, ulong documentKeyMask)
 {
     using (LockWrite())
     {
         for (var i = binarySearchRange.startOffset; i < binarySearchRange.endOffset; ++i)
         {
             var record = m_StoreData[(int)i];
             if ((record.key.documentKey & documentKeyMask) != 0)
             {
                 var newRecord = new PropertyDatabaseRecord(record.recordKey, record.recordValue, false);
                 m_StoreData[(int)i] = newRecord;
             }
         }
     }
 }
예제 #5
0
 void InvalidateRange(BinarySearchRange binarySearchRange, bool sync)
 {
     using (LockWrite())
     {
         for (var i = binarySearchRange.startOffset; i < binarySearchRange.endOffset; ++i)
         {
             var record    = GetRecord(i);
             var newRecord = new PropertyDatabaseRecord(record.recordKey, record.recordValue, false);
             WriteRecord(newRecord, i, false);
         }
         if (sync)
         {
             Sync();
         }
     }
 }
예제 #6
0
 void InvalidateMaskRange(BinarySearchRange binarySearchRange, ulong documentKeyMask, bool sync)
 {
     using (LockWrite())
     {
         for (var i = binarySearchRange.startOffset; i < binarySearchRange.endOffset; ++i)
         {
             var record = GetRecord(i);
             if ((record.key.documentKey & documentKeyMask) != 0)
             {
                 var newRecord = new PropertyDatabaseRecord(record.recordKey, record.recordValue, false);
                 WriteRecord(newRecord, i, false);
             }
         }
         if (sync)
         {
             Sync();
         }
     }
 }
예제 #7
0
        public static BinarySearchRange FindRange <TRangeData>(IBinarySearchRange <TRangeData> range, IBinarySearchRangeData <TRangeData> data)
        {
            #if PACKAGE_PERFORMANCE_TRACKING
            // using (new PerformanceTracker(nameof(FindRange)))
            #endif
            {
                var nbValues = data.length;
                if (nbValues == 0)
                {
                    return(BinarySearchRange.invalid);
                }

                var binarySearchRangeStart = new BinarySearchRange {
                    startOffset = 0, endOffset = nbValues, halfOffset = nbValues / 2
                };
                var binarySearchRangeEnd = new BinarySearchRange {
                    startOffset = 0, endOffset = nbValues, halfOffset = nbValues / 2
                };
                var foundStartOffset = false;
                var foundEndOffset   = false;
                while (!foundStartOffset || !foundEndOffset)
                {
                    if (!foundStartOffset)
                    {
                        // Update StartIndex
                        var startValue = data[binarySearchRangeStart.halfOffset];
                        if (range.StartIsInRange(startValue))
                        {
                            binarySearchRangeStart.endOffset  = binarySearchRangeStart.halfOffset;
                            binarySearchRangeStart.halfOffset = binarySearchRangeStart.startOffset + (binarySearchRangeStart.endOffset - binarySearchRangeStart.startOffset) / 2;

                            if (binarySearchRangeStart.endOffset == binarySearchRangeStart.halfOffset)
                            {
                                foundStartOffset = true;
                            }
                        }
                        else
                        {
                            // value is outside of the file
                            if (binarySearchRangeStart.halfOffset >= nbValues - 1)
                            {
                                return(BinarySearchRange.invalid);
                            }

                            binarySearchRangeStart.startOffset = binarySearchRangeStart.halfOffset;
                            binarySearchRangeStart.halfOffset  = binarySearchRangeStart.startOffset + (binarySearchRangeStart.endOffset - binarySearchRangeStart.startOffset) / 2;

                            if (binarySearchRangeStart.startOffset == binarySearchRangeStart.halfOffset)
                            {
                                foundStartOffset = true;
                            }
                        }
                    }

                    if (!foundEndOffset)
                    {
                        // Update EndIndex
                        var endValue = data[binarySearchRangeEnd.halfOffset];
                        if (range.EndIsInRange(endValue))
                        {
                            binarySearchRangeEnd.startOffset = binarySearchRangeEnd.halfOffset;
                            binarySearchRangeEnd.halfOffset  = binarySearchRangeEnd.startOffset + (binarySearchRangeEnd.endOffset - binarySearchRangeEnd.startOffset) / 2;

                            if (binarySearchRangeEnd.startOffset == binarySearchRangeEnd.halfOffset)
                            {
                                foundEndOffset = true;
                            }
                        }
                        else
                        {
                            // value is outside of the file
                            if (binarySearchRangeEnd.halfOffset == 0)
                            {
                                return(BinarySearchRange.invalid);
                            }

                            binarySearchRangeEnd.endOffset  = binarySearchRangeEnd.halfOffset;
                            binarySearchRangeEnd.halfOffset = binarySearchRangeEnd.startOffset + (binarySearchRangeEnd.endOffset - binarySearchRangeEnd.startOffset) / 2;

                            if (binarySearchRangeEnd.endOffset == binarySearchRangeEnd.halfOffset)
                            {
                                foundEndOffset = true;
                            }
                        }
                    }
                }

                // We take the endOffset because we know the values of interests lie on these offset.
                return(new BinarySearchRange {
                    startOffset = binarySearchRangeStart.endOffset, endOffset = binarySearchRangeEnd.endOffset
                });
            }
        }