Skip to content

Hash on stream instead of the entire file - #481

Open
liyimeng wants to merge 1 commit into
ROCm:mainfrom
liyimeng:main
Open

Hash on stream instead of the entire file#481
liyimeng wants to merge 1 commit into
ROCm:mainfrom
liyimeng:main

Conversation

@liyimeng

@liyimeng liyimeng commented Apr 9, 2026

Copy link
Copy Markdown

Instead of pulling in huge model file into memory to caculate hash, take stream instead.

Instead of pulling in huge model file into memory to caculate hash, take stream instead.

Signed-off-by: Liyi Meng <meng.mobile@gmail.com>

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates model download integrity checking to avoid loading entire model files into memory when computing Git blob OIDs, improving scalability for large files.

Changes:

  • Refactors calculate_git_blob_oid() to hash the Git blob header and then stream file contents into the SHA1 implementation.
  • Adds additional stream state checks around seekg() / tellg() in calculate_git_blob_oid().
  • Minor formatting adjustment near the hash-checking call site.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +40 to +46
std::streampos end_pos = file.tellg();
if (end_pos == std::streampos(-1)) {
return "";
}

std::string blob_data = oss.str();
size_t size = static_cast<size_t>(end_pos);
file.clear();

Copilot AI Apr 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

end_pos (a std::streampos) is cast directly to size_t. On some platforms/configs this can truncate/overflow for large files (e.g., 32-bit builds or very large model files), producing an incorrect Git blob OID and causing spurious hash mismatches. Consider computing the byte size via std::filesystem::file_size() (with error_code) or converting through std::streamoff and explicitly checking end_pos < 0 / end_pos > std::numeric_limits<size_t>::max() before casting.

Copilot uses AI. Check for mistakes.
return "";
}

std::string header = "blob " + std::to_string(size) + '\0';

Copilot AI Apr 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Building the Git blob header as "blob " + std::to_string(size) + '\0' relies on an embedded NUL in a std::string, which is easy to miss during maintenance. Consider constructing the header without the terminator and then push_back('\0') (or equivalent) so it’s more obvious that the NUL is intentional.

Suggested change
std::string header = "blob " + std::to_string(size) + '\0';
std::string header = "blob " + std::to_string(size);
header.push_back('\0');

Copilot uses AI. Check for mistakes.
@ZaneNi

ZaneNi commented May 1, 2026

Copy link
Copy Markdown
Contributor

@liyimeng Thank you for your contribution!

Could you please review Copilot’s suggestion?

Also, I’m not sure how to evaluate the difference, could you share how to test it or provide some results, such as memory usage before and after using the streaming method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants