Skip to content

Conversation

@congqixia
Copy link
Contributor

Related to #44956

Update milvus-storage dependency to use new Manifest structure where column groups are accessed via manifest->columnGroups(). Adapt to renamed FFI functions (loon_ prefix) and updated Transaction API.

Related to milvus-io#44956

Update milvus-storage dependency to use new Manifest structure where column
groups are accessed via manifest->columnGroups(). Adapt to renamed FFI
functions (loon_ prefix) and updated Transaction API.

Signed-off-by: Congqi Xia <[email protected]>
@sre-ci-robot sre-ci-robot requested review from czs007 and sunby January 15, 2026 06:28
@sre-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: congqixia

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sre-ci-robot sre-ci-robot added approved size/L Denotes a PR that changes 100-499 lines. area/compilation labels Jan 15, 2026
@gemini-code-assist
Copy link

Summary of Changes

Hello @congqixia, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request primarily focuses on upgrading the milvus-storage dependency, which necessitates widespread adaptations across the codebase. The core purpose is to integrate the latest milvus-storage features and improvements, ensuring the system remains current with its underlying storage mechanisms. This involves updating how manifest data, particularly column groups, is accessed and processed, as well as aligning with new FFI function names and transaction handling paradigms.

Highlights

  • Milvus-Storage Dependency Update: The milvus-storage dependency has been updated to commit 88c2551, bringing in significant API changes.
  • New Manifest Structure Adoption: The system now utilizes the new Manifest structure from milvus-storage, where column groups are accessed through the manifest->columnGroups() method instead of direct accessors.
  • FFI Interface Renaming: All Foreign Function Interface (FFI) functions have been adapted to their new loon_ prefixed names, ensuring compatibility with the updated milvus-storage library.
  • Transaction API Updates: The Transaction API usage has been revised to align with the latest milvus-storage changes, including new methods for transaction management and manifest retrieval.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@mergify mergify bot added dco-passed DCO check passed. kind/enhancement Issues or changes related to enhancement labels Jan 15, 2026
@sre-ci-robot
Copy link
Contributor

[ci-v2-notice]
Notice: New ci-v2 system is enabled for this PR.

To rerun ci-v2 checks, comment with:

  • /ci-rerun-code-check // for ci-v2/code-check
  • /ci-rerun-build // for ci-v2/build
  • /ci-rerun-ut-integration // for ci-v2/ut-integration, will rerun ci-v2/build
  • /ci-rerun-ut-go // for ci-v2/ut-go, will rerun ci-v2/build
  • /ci-rerun-ut-cpp // for ci-v2/ut-cpp
  • /ci-rerun-ut // for all ci-v2/ut-integration, ci-v2/ut-go, ci-v2/ut-cpp, will rerun ci-v2/build
  • /ci-rerun-e2e-arm // for ci-v2/e2e-arm
  • /ci-rerun-e2e-default // for ci-v2/e2e-default

If you have any questions or requests, please contact @zhikunyao.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the milvus-storage dependency and adapts the codebase to its new API. The changes include using a new Manifest structure, renamed FFI functions with a loon_ prefix, and an updated Transaction API. The changes are widespread across both C++ and Go code.

While most of the changes correctly adapt to the new API, I've found some critical issues in the Go FFI wrapper code related to memory and resource lifetime management. Specifically, there's a use-after-free bug in packed_reader_ffi.go that could lead to crashes, and potential memory leaks in both packed_reader_ffi.go and packed_writer_ffi.go. These issues need to be addressed to ensure stability.

Comment on lines +187 to 217
func GetManifestHandle(manifestPath string, storageConfig *indexpb.StorageConfig) (loonManifestHandle *C.LoonManifest, err error) {
var cManifestHandle *C.LoonManifest
basePath, version, err := UnmarshalManfestPath(manifestPath)
if err != nil {
return cColumnGroups, err
return cManifestHandle, err
}
log.Info("GetManifest", zap.String("manifestPath", manifestPath), zap.String("basePath", basePath), zap.Int64("version", version))

cProperties, err := MakePropertiesFromStorageConfig(storageConfig, nil)
if err != nil {
return cColumnGroups, err
return cManifestHandle, err
}
cBasePath := C.CString(basePath)
defer C.free(unsafe.Pointer(cBasePath))

result := C.get_column_groups_by_version(cBasePath, cProperties, C.int64_t(version), &cColumnGroups)
err = HandleFFIResult(result)
var cTransactionHandle C.LoonTransactionHandle
result := C.loon_transaction_begin(cBasePath, cProperties, C.int64_t(version), 1, &cTransactionHandle)
err = HandleLoonFFIResult(result)
if err != nil {
return cColumnGroups, err
return cManifestHandle, err
}
defer C.loon_transaction_destroy(cTransactionHandle)

return cColumnGroups, nil
result = C.loon_transaction_get_manifest(cTransactionHandle, &cManifestHandle)
err = HandleLoonFFIResult(result)
if err != nil {
return cManifestHandle, err
}

return cManifestHandle, nil
}

Choose a reason for hiding this comment

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

critical

This function has two significant resource lifetime management issues that will likely lead to a crash and a memory leak.

  1. Use-after-free on cManifestHandle: The defer C.loon_transaction_destroy(cTransactionHandle) at line 208 will be executed when GetManifestHandle returns. The returned cManifestHandle is obtained from cTransactionHandle. It's highly likely that destroying the transaction handle invalidates the manifest handle, making it a dangling pointer. The caller NewFFIPackedReader will then use this dangling pointer, leading to a use-after-free, which can cause crashes or unpredictable behavior.

  2. Memory leak of cProperties: The cProperties object is created by MakePropertiesFromStorageConfig at line 195. It is not freed anywhere in this function. This will cause a memory leak on every call. There should be a defer C.loon_properties_free(cProperties) call.

To fix this, you should probably refactor this function and its caller. GetManifestHandle should not destroy the transaction handle. The caller should be responsible for its lifetime. For example, GetManifestHandle could return the transaction handle as well, and the caller would defer its destruction after it's done using the manifest handle. The properties object should also be freed within this function after it's no longer needed.

Comment on lines 168 to 201
func (pw *FFIPackedWriter) Close() (string, error) {
var cColumnGroups C.ColumnGroupsHandle
var cColumnGroups *C.LoonColumnGroups

result := C.writer_close(pw.cWriterHandle, nil, nil, 0, &cColumnGroups)
if err := HandleFFIResult(result); err != nil {
result := C.loon_writer_close(pw.cWriterHandle, nil, nil, 0, &cColumnGroups)
if err := HandleLoonFFIResult(result); err != nil {
return "", err
}

cBasePath := C.CString(pw.basePath)
defer C.free(unsafe.Pointer(cBasePath))
var transationHandle C.TransactionHandle
var transationHandle C.LoonTransactionHandle

result = C.transaction_begin(cBasePath, pw.cProperties, &transationHandle, C.int64_t(pw.baseVersion))
if err := HandleFFIResult(result); err != nil {
result = C.loon_transaction_begin(cBasePath, pw.cProperties, C.int64_t(pw.baseVersion), 1, &transationHandle)
if err := HandleLoonFFIResult(result); err != nil {
return "", err
}
defer C.transaction_destroy(transationHandle)
defer C.loon_transaction_destroy(transationHandle)

// #define LOON_TRANSACTION_UPDATE_ADDFILES 0
// #define LOON_TRANSACTION_UPDATE_ADDFEILD 1
// #define LOON_TRANSACTION_UPDATE_MAX 2

// #define LOON_TRANSACTION_RESOLVE_FAIL 0
// #define LOON_TRANSACTION_RESOLVE_MERGE 1
// #define LOON_TRANSACTION_RESOLVE_MAX 2
result = C.loon_transaction_append_files(transationHandle, cColumnGroups)
if err := HandleLoonFFIResult(result); err != nil {
return "", err
}

var commitResult C.TransactionCommitResult
result = C.transaction_commit(transationHandle, C.int16_t(0), C.int16_t(0), cColumnGroups, &commitResult)
if err := HandleFFIResult(result); err != nil {
var cCommitVersion C.int64_t
result = C.loon_transaction_commit(transationHandle, &cCommitVersion)
if err := HandleLoonFFIResult(result); err != nil {
return "", err
}

log.Info("FFI writer closed", zap.Int64("version", int64(commitResult.committed_version)))
log.Info("FFI writer closed", zap.Int64("version", int64(cCommitVersion)))

defer C.properties_free(pw.cProperties)
return MarshalManifestPath(pw.basePath, int64(commitResult.committed_version)), nil
defer C.loon_properties_free(pw.cProperties)
return MarshalManifestPath(pw.basePath, int64(cCommitVersion)), nil
}

Choose a reason for hiding this comment

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

high

There appears to be a potential memory leak for cColumnGroups within this Close function.

The variable cColumnGroups is populated by C.loon_writer_close at line 171. It's a pointer to C.LoonColumnGroups, which is likely allocated on the heap within the C++ FFI function. However, there is no corresponding call to free this memory within the Close function. If loon_transaction_append_files does not take ownership and free the memory, this will result in a memory leak every time Close is called.

Please verify the ownership semantics of cColumnGroups and add a call to free it if necessary, likely via a C.loon_column_groups_free(cColumnGroups) function if one exists.

@codecov
Copy link

codecov bot commented Jan 15, 2026

Codecov Report

❌ Patch coverage is 37.50000% with 55 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.43%. Comparing base (2572770) to head (63950fc).
⚠️ Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
internal/core/src/storage/loon_ffi/util.cpp 0.00% 18 Missing ⚠️
...nternal/core/src/storage/loon_ffi/ffi_reader_c.cpp 0.00% 11 Missing ⚠️
internal/storagev2/packed/packed_reader_ffi.go 64.70% 5 Missing and 1 partial ⚠️
internal/storagev2/packed/packed_writer_ffi.go 72.72% 2 Missing and 4 partials ⚠️
internal/core/src/segcore/SegmentLoadInfo.cpp 0.00% 4 Missing ⚠️
internal/core/src/segcore/SegmentGrowingImpl.cpp 0.00% 3 Missing ⚠️
internal/core/src/storage/Util.cpp 0.00% 3 Missing ⚠️
...rnal/core/src/segcore/ChunkedSegmentSealedImpl.cpp 0.00% 2 Missing ⚠️
internal/storagev2/packed/ffi_common.go 75.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #47085      +/-   ##
==========================================
- Coverage   76.56%   76.43%   -0.14%     
==========================================
  Files        2016     2016              
  Lines      326928   326313     -615     
==========================================
- Hits       250316   249404     -912     
- Misses      68652    68918     +266     
- Partials     7960     7991      +31     
Components Coverage Δ
Client 75.68% <ø> (ø)
Core 82.94% <0.00%> (-0.01%) ⬇️
Go 74.76% <70.21%> (-0.21%) ⬇️
Files with missing lines Coverage Δ
internal/core/src/segcore/SegmentGrowingImpl.h 71.31% <ø> (ø)
...rnal/core/src/segcore/ChunkedSegmentSealedImpl.cpp 62.69% <0.00%> (ø)
internal/storagev2/packed/ffi_common.go 55.79% <75.00%> (ø)
internal/core/src/segcore/SegmentGrowingImpl.cpp 60.13% <0.00%> (-0.06%) ⬇️
internal/core/src/storage/Util.cpp 80.45% <0.00%> (-0.09%) ⬇️
internal/core/src/segcore/SegmentLoadInfo.cpp 34.30% <0.00%> (-0.21%) ⬇️
internal/storagev2/packed/packed_reader_ffi.go 68.30% <64.70%> (-0.35%) ⬇️
internal/storagev2/packed/packed_writer_ffi.go 55.14% <72.72%> (-3.43%) ⬇️
...nternal/core/src/storage/loon_ffi/ffi_reader_c.cpp 0.00% <0.00%> (ø)
internal/core/src/storage/loon_ffi/util.cpp 3.54% <0.00%> (-0.03%) ⬇️

... and 46 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mergify mergify bot added the ci-passed label Jan 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved area/compilation ci-passed dco-passed DCO check passed. kind/enhancement Issues or changes related to enhancement size/L Denotes a PR that changes 100-499 lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants