mirror of
https://github.com/zrepl/zrepl.git
synced 2025-07-01 06:50:11 +02:00
zfs: use channel as iterator for ZFSList results
The old approach with ZFSList would keep the two-dimensional array of lines and their fields in memory (for a short time), which could easily consume 100s of MiB with > 10000 snapshots / bookmarks (see #34) fixes #61
This commit is contained in:
@ -1,6 +1,9 @@
|
||||
package zfs
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type DatasetFilter interface {
|
||||
Filter(p *DatasetPath) (pass bool, err error)
|
||||
@ -12,15 +15,21 @@ func ZFSListMapping(filter DatasetFilter) (datasets []*DatasetPath, err error) {
|
||||
panic("filter must not be nil")
|
||||
}
|
||||
|
||||
var lines [][]string
|
||||
lines, err = ZFSList([]string{"name"}, "-r", "-t", "filesystem,volume")
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
rchan := make(chan ZFSListResult)
|
||||
go ZFSListChan(ctx, rchan, []string{"name"}, "-r", "-t", "filesystem,volume")
|
||||
|
||||
datasets = make([]*DatasetPath, 0, len(lines))
|
||||
datasets = make([]*DatasetPath, 0)
|
||||
for r := range rchan {
|
||||
|
||||
for _, line := range lines {
|
||||
if r.err != nil {
|
||||
err = r.err
|
||||
return
|
||||
}
|
||||
|
||||
var path *DatasetPath
|
||||
if path, err = NewDatasetPath(line[0]); err != nil {
|
||||
if path, err = NewDatasetPath(r.fields[0]); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user