Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions benchmarks/cosmos-exim/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ func runExport(dbPath string) (int64, map[string][]*iavl.ExportNode, error) {
if err != nil {
return 0, nil, err
}
defer exporter.Close()
for {
node, err := exporter.Next()
if errors.Is(err, iavl.ErrorExportDone) {
Expand All @@ -137,6 +136,7 @@ func runExport(dbPath string) (int64, map[string][]*iavl.ExportNode, error) {
export = append(export, node)
stats.AddNode(node)
}
exporter.Close()
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Potential resource leak on early error return.

While moving from defer to explicit Close() addresses the accumulation issue in loops, the current placement could lead to resource leaks if errors occur in the processing loop (lines 129-138).

Consider refactoring the per-store logic into a helper function where defer can be used safely:

+func exportStore(name string, ldb idbm.DB, version int64) ([]*iavl.ExportNode, Stats, error) {
+	db := idbm.NewPrefixDB(ldb, []byte("s/k:"+name+"/"))
+	tree := iavl.NewMutableTree(db, 0, false, iavl.NewNopLogger())
+	
+	stats := Stats{}
+	export := make([]*iavl.ExportNode, 0, 100000)
+	
+	storeVersion, err := tree.LoadVersion(0)
+	if err != nil {
+		return nil, stats, err
+	}
+	if storeVersion == 0 {
+		return export, stats, nil
+	}
+	
+	itree, err := tree.GetImmutable(version)
+	if err != nil {
+		return nil, stats, err
+	}
+	
+	start := time.Now().UTC()
+	exporter, err := itree.Export()
+	if err != nil {
+		return nil, stats, err
+	}
+	defer exporter.Close()
+	
+	for {
+		node, err := exporter.Next()
+		if errors.Is(err, iavl.ErrorExportDone) {
+			break
+		} else if err != nil {
+			return nil, stats, err
+		}
+		export = append(export, node)
+		stats.AddNode(node)
+	}
+	
+	stats.AddDurationSince(start)
+	return export, stats, nil
+}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In benchmarks/cosmos-exim/main.go at line 139, calling exporter.Close()
explicitly here risks resource leaks if an error occurs earlier in the
processing loop (lines 129-138). Refactor the per-store processing logic into a
separate helper function so you can use defer exporter.Close() safely within
that function, ensuring the exporter is always closed properly even if errors
occur.

stats.AddDurationSince(start)
fmt.Printf("%-13v: %v\n", name, stats.String())
totalStats.Add(stats)
Expand Down Expand Up @@ -173,7 +173,6 @@ func runImport(version int64, exports map[string][]*iavl.ExportNode) error {
if err != nil {
return err
}
defer importer.Close()
for _, node := range exports[name] {
err = importer.Add(node)
if err != nil {
Expand All @@ -185,6 +184,7 @@ func runImport(version int64, exports map[string][]*iavl.ExportNode) error {
if err != nil {
return err
}
importer.Close()
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Potential resource leak on early error return.

Similar to the export function, this explicit Close() call could be skipped if errors occur in the processing loop (lines 176-182) or during commit (line 183).

Consider refactoring to a helper function:

+func importStore(name string, version int64, nodes []*iavl.ExportNode) (Stats, error) {
+	tempdir, err := os.MkdirTemp("", name)
+	if err != nil {
+		return Stats{}, err
+	}
+	defer os.RemoveAll(tempdir)
+	
+	start := time.Now()
+	stats := Stats{}
+	
+	newDB, err := idbm.NewGoLevelDB(name, tempdir)
+	if err != nil {
+		return stats, err
+	}
+	
+	newTree := iavl.NewMutableTree(newDB, 0, false, iavl.NewNopLogger())
+	importer, err := newTree.Import(version)
+	if err != nil {
+		return stats, err
+	}
+	defer importer.Close()
+	
+	for _, node := range nodes {
+		err = importer.Add(node)
+		if err != nil {
+			return stats, err
+		}
+		stats.AddNode(node)
+	}
+	
+	err = importer.Commit()
+	if err != nil {
+		return stats, err
+	}
+	
+	stats.AddDurationSince(start)
+	return stats, nil
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
importer.Close()
func importStore(name string, version int64, nodes []*iavl.ExportNode) (Stats, error) {
tempdir, err := os.MkdirTemp("", name)
if err != nil {
return Stats{}, err
}
defer os.RemoveAll(tempdir)
start := time.Now()
stats := Stats{}
newDB, err := idbm.NewGoLevelDB(name, tempdir)
if err != nil {
return stats, err
}
newTree := iavl.NewMutableTree(newDB, 0, false, iavl.NewNopLogger())
importer, err := newTree.Import(version)
if err != nil {
return stats, err
}
defer importer.Close()
for _, node := range nodes {
if err = importer.Add(node); err != nil {
return stats, err
}
stats.AddNode(node)
}
if err = importer.Commit(); err != nil {
return stats, err
}
stats.AddDurationSince(start)
return stats, nil
}
🤖 Prompt for AI Agents
In benchmarks/cosmos-exim/main.go at line 187, the explicit call to
importer.Close() may be skipped if an error occurs earlier in the processing
loop or during commit, causing a resource leak. Refactor by moving the Close()
call into a deferred function immediately after the importer is created,
ensuring it always executes regardless of errors. This can be done by defining a
helper function or using defer directly after importer initialization.

stats.AddDurationSince(start)
fmt.Printf("%-12v: %v\n", name, stats.String())
totalStats.Add(stats)
Expand Down
Loading