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); } }