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:
Christian Schwarz
2018-02-18 13:28:46 +01:00
parent aa92261ea7
commit 3ba3648f0f
4 changed files with 95 additions and 13 deletions

View File

@ -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
}