protected async ValueTask <(bool Success, uint Index)> TryFindIdAsync(GitId id) { if (FanOut == null) { return(false, 0); } uint first = (id[0] == 0) ? 0 : FanOut[id[0] - 1]; uint countAfter = FanOut[id[0]]; if (first == countAfter) // Includes countAfter=0, which overflows the loop { // No need to check. return(false, 0); } uint c = countAfter; while (first + 1 < c) { uint mid = first + (c - first) / 2; var check = await GetGitIdByIndexAsync(mid).ConfigureAwait(false); int n = id.CompareTo(check); if (n == 0) { return(true, mid); } else if (n < 0) { c = mid; } else { first = mid + 1; } } if (first >= countAfter) { return(false, countAfter); } var check2 = await GetGitIdByIndexAsync(first).ConfigureAwait(false); int n2 = id.CompareTo(check2); if (n2 == 0) { return(true, first); } else if (n2 > 0) { first++; } return(false, first); }
private bool TryFindId(byte[] oids, GitId oid, out uint index) { int sz; if (oids.Length == 0) { index = 0; return(false); } if (_ver == 2) { sz = _idType.HashLength(); } else if (_ver == 1) { sz = _idType.HashLength() + 4; } else { index = 0; return(false); } int first = 0, count = oids.Length / sz; int c = count; if (c == 0) { index = 0; return(false); } while (first + 1 < c) { int mid = first + (c - first) / 2; var check = GitId.FromByteArrayOffset(_idType, oids, sz * mid); int n = oid.CompareTo(check); if (n == 0) { index = (uint)mid; return(true); } else if (n < 0) { c = mid; } else { first = mid + 1; } } if (first >= count) { index = (uint)count; return(false); } var check2 = GitId.FromByteArrayOffset(_idType, oids, sz * first); index = (uint)first; c = oid.CompareTo(check2); if (c == 0) { return(true); } else if (c > 0) { index++; } return(false); }