public bool TryResolve(FIoChunkId chunkId, out FIoOffsetAndLength outOffsetLength) { if (TocResource.ChunkPerfectHashSeeds != null) { var chunkCount = TocResource.Header.TocEntryCount; if (chunkCount == 0) { outOffsetLength = default; return(false); } var seedCount = (uint)TocResource.ChunkPerfectHashSeeds.Length; var seedIndex = (uint)(chunkId.HashWithSeed(0) % seedCount); var seed = TocResource.ChunkPerfectHashSeeds[seedIndex]; if (seed == 0) { outOffsetLength = default; return(false); } uint slot; if (seed < 0) { var seedAsIndex = (uint)(-seed - 1); if (seedAsIndex < chunkCount) { slot = seedAsIndex; } else { // Entry without perfect hash return(TryResolveImperfect(chunkId, out outOffsetLength)); } } else { slot = (uint)(chunkId.HashWithSeed(seed) % chunkCount); } if (TocResource.ChunkIds[slot].GetHashCode() == chunkId.GetHashCode()) { outOffsetLength = TocResource.ChunkOffsetLengths[slot]; return(true); } outOffsetLength = default; return(false); } return(TryResolveImperfect(chunkId, out outOffsetLength)); }
private bool TryResolveImperfect(FIoChunkId chunkId, out FIoOffsetAndLength outOffsetLength) { if (TocImperfectHashMapFallback != null) { return(TocImperfectHashMapFallback.TryGetValue(chunkId, out outOffsetLength)); } var chunkIndex = Array.IndexOf(TocResource.ChunkIds, chunkId); if (chunkIndex == -1) { outOffsetLength = default; return(false); } outOffsetLength = TocResource.ChunkOffsetLengths[chunkIndex]; return(true); }