示例#1
0
        private void RecoverFromPage(long startRecoveryAddress,
                                     long fromLogicalAddressInPage,
                                     long untilLogicalAddressInPage,
                                     long pageLogicalAddress,
                                     long pagePhysicalAddress,
                                     int version)
        {
            var key         = default(Key *);
            var hash        = default(long);
            var tag         = default(ushort);
            var info        = default(RecordInfo *);
            var pointer     = default(long);
            var recordStart = default(long);
            var bucket      = default(HashBucket *);
            var entry       = default(HashBucketEntry);
            var slot        = default(int);

            pointer = fromLogicalAddressInPage;
            while (pointer < untilLogicalAddressInPage)
            {
                recordStart = pagePhysicalAddress + pointer;
                info        = Layout.GetInfo(recordStart);

                if (info->IsNull())
                {
                    pointer += RecordInfo.GetLength();
                    continue;
                }

                if (!info->Invalid)
                {
                    key  = Layout.GetKey(recordStart);
                    hash = Key.GetHashCode(key);
                    tag  = (ushort)((ulong)hash >> Constants.kHashTagShift);

                    entry = default(HashBucketEntry);
                    FindOrCreateTag(hash, tag, ref bucket, ref slot, ref entry);

                    if (info->Version <= version)
                    {
                        entry.Address   = pageLogicalAddress + pointer;
                        entry.Tag       = tag;
                        entry.Pending   = false;
                        entry.Tentative = false;
                        bucket->bucket_entries[slot] = entry.word;
                    }
                    else
                    {
                        info->Invalid = true;
                        if (info->PreviousAddress < startRecoveryAddress)
                        {
                            entry.Address   = info->PreviousAddress;
                            entry.Tag       = tag;
                            entry.Pending   = false;
                            entry.Tentative = false;
                            bucket->bucket_entries[slot] = entry.word;
                        }
                    }
                }
                pointer += Layout.GetPhysicalSize(recordStart);
            }
        }