mirror of
https://github.com/versity/scoutfs-go.git
synced 2026-09-19 22:44:29 +00:00
add query totals by group
This commit is contained in:
@@ -4,6 +4,14 @@
|
||||
// that can be found in the LICENSE file in the root of the source
|
||||
// tree.
|
||||
|
||||
// This example returns the values of a "group" of totl counts/values
|
||||
// given a 2 uint64 id group tuple. Or it will return the single value
|
||||
// for a unique 3 uint64 id triple.
|
||||
|
||||
// id1 id2 id3
|
||||
// |--group--|
|
||||
// |--specific id---|
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -16,8 +24,9 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 5 || os.Args[1] == "-h" {
|
||||
fmt.Fprintln(os.Stderr, "usage:", os.Args[0], "<scoutfs mount point> <id1> <id2> <id3>")
|
||||
if (len(os.Args) != 4 && len(os.Args) != 5) || os.Args[1] == "-h" {
|
||||
fmt.Fprintln(os.Stderr, "usage:", os.Args[0],
|
||||
"<scoutfs mount point> <id1> <id2> or <scoutfs mount point> <id1> <id2> <id3>")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -35,16 +44,33 @@ func main() {
|
||||
if err != nil {
|
||||
log.Fatalln("error parsing id2:", err)
|
||||
}
|
||||
|
||||
if len(os.Args) == 4 {
|
||||
tg := scoutfs.NewTotalsGroup(f, u1, u2, 10)
|
||||
for {
|
||||
ttls, err := tg.Next()
|
||||
if err != nil {
|
||||
log.Fatalln("error read totals:", err)
|
||||
}
|
||||
if ttls == nil {
|
||||
break
|
||||
}
|
||||
for _, t := range ttls {
|
||||
fmt.Println("id:", t.ID[2], "xattrs match:", t.Count, "total value:", t.Total)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
u3, err := strconv.ParseUint(os.Args[4], 10, 64)
|
||||
if err != nil {
|
||||
log.Fatalln("error parsing id3:", err)
|
||||
log.Fatalln("error parsing id2:", err)
|
||||
}
|
||||
|
||||
t, err := scoutfs.ReadXattrTotals(f, u1, u2, u3)
|
||||
if err != nil {
|
||||
log.Fatalln("error read totals:", err)
|
||||
log.Fatalln("error reading totals:", err)
|
||||
}
|
||||
|
||||
fmt.Println("xattrs match: ", t.Count)
|
||||
fmt.Println("total value : ", t.Total)
|
||||
fmt.Println("Count", t.Count)
|
||||
fmt.Println("Total", t.Total)
|
||||
}
|
||||
|
||||
+78
@@ -12,6 +12,7 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -870,6 +871,8 @@ type XattrTotal struct {
|
||||
Total uint64
|
||||
// Count is number of xattrs matching ids
|
||||
Count uint64
|
||||
// ID is the id for this total
|
||||
ID [3]uint64
|
||||
}
|
||||
|
||||
// ReadXattrTotals returns the XattrTotal for the given id
|
||||
@@ -895,3 +898,78 @@ func ReadXattrTotals(f *os.File, id1, id2, id3 uint64) (XattrTotal, error) {
|
||||
Count: totls[0].Count,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type TotalsGroup struct {
|
||||
totls []xattrTotal
|
||||
pos [3]uint64
|
||||
id1 uint64
|
||||
id2 uint64
|
||||
count int
|
||||
f *os.File
|
||||
done bool
|
||||
}
|
||||
|
||||
// NewTotalsGroup creates a query to get the totals values for a defined
|
||||
// group of totls (group is defined to match first 2 identifiers). Count
|
||||
// specifies max number returned for each Next() call.
|
||||
func NewTotalsGroup(f *os.File, id1, id2 uint64, count int) *TotalsGroup {
|
||||
totls := make([]xattrTotal, count)
|
||||
|
||||
return &TotalsGroup{
|
||||
totls: totls,
|
||||
f: f,
|
||||
id1: id1,
|
||||
id2: id2,
|
||||
count: count,
|
||||
pos: [3]uint64{id1, id2, 0},
|
||||
}
|
||||
}
|
||||
|
||||
// Next returns next set of total values for the group
|
||||
func (t *TotalsGroup) Next() ([]XattrTotal, error) {
|
||||
if t.done {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
query := readXattrTotals{
|
||||
Pos_name: t.pos,
|
||||
Totals_ptr: uint64(uintptr(unsafe.Pointer(&t.totls[0]))),
|
||||
Totals_bytes: sizeofxattrTotal * uint64(t.count),
|
||||
}
|
||||
|
||||
n, err := scoutfsctl(t.f, IOCREADXATTRTOTALS, unsafe.Pointer(&query))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n == 0 {
|
||||
t.done = true
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
t.pos = t.totls[n-1].Name
|
||||
if t.pos[2] == math.MaxUint64 {
|
||||
t.done = true
|
||||
}
|
||||
t.pos[2]++
|
||||
|
||||
ret := make([]XattrTotal, n)
|
||||
for i := range ret {
|
||||
if t.totls[i].Name[0] != t.id1 || t.totls[i].Name[1] != t.id2 {
|
||||
t.done = true
|
||||
// id sequence we want is done
|
||||
return ret[:i], nil
|
||||
}
|
||||
ret[i].Count = t.totls[i].Count
|
||||
ret[i].Total = t.totls[i].Total
|
||||
ret[i].ID = t.totls[i].Name
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Reset resets the totl query to the start of the group id again
|
||||
func (t *TotalsGroup) Reset() {
|
||||
t.done = false
|
||||
t.pos[0] = t.id1
|
||||
t.pos[1] = t.id2
|
||||
t.pos[2] = 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user