func (q *Quasar) QueryNearestValue(id uuid.UUID, time int64, backwards bool, gen uint64) (qtree.Record, uint64, error) { tr, err := qtree.NewReadQTree(q.bs, id, gen) if err != nil { return qtree.Record{}, 0, err } rv, err := tr.FindNearestValue(time, backwards) return rv, tr.Generation(), err }
//These functions are the API. TODO add all the bounds checking on PW, and sanity on start/end func (q *Quasar) QueryValues(id uuid.UUID, start int64, end int64, gen uint64) ([]qtree.Record, uint64, error) { tr, err := qtree.NewReadQTree(q.bs, id, gen) if err != nil { return nil, 0, err } rv, err := tr.ReadStandardValuesBlock(start, end) return rv, tr.Generation(), err }
func (q *Quasar) QueryValuesStream(id uuid.UUID, start int64, end int64, gen uint64) (chan qtree.Record, chan error, uint64) { tr, err := qtree.NewReadQTree(q.bs, id, gen) if err != nil { return nil, nil, 0 } recordc := make(chan qtree.Record) errc := make(chan error) go tr.ReadStandardValuesCI(recordc, errc, start, end) return recordc, errc, tr.Generation() }
func (q *Quasar) QueryStatisticalValuesStream(id uuid.UUID, start int64, end int64, gen uint64, pointwidth uint8) (chan qtree.StatRecord, chan error, uint64) { fmt.Printf("QSV1 s=%v e=%v pw=%v\n", start, end, pointwidth) start &^= ((1 << pointwidth) - 1) end &^= ((1 << pointwidth) - 1) rvv := make(chan qtree.StatRecord, 1024) rve := make(chan error) tr, err := qtree.NewReadQTree(q.bs, id, gen) if err != nil { return nil, nil, 0 } go tr.QueryStatisticalValues(rvv, rve, start, end, pointwidth) return rvv, rve, tr.Generation() }
func (q *Quasar) QueryStatisticalValues(id uuid.UUID, start int64, end int64, gen uint64, pointwidth uint8) ([]qtree.StatRecord, uint64, error) { //fmt.Printf("QSV0 s=%v e=%v pw=%v\n", start, end, pointwidth) start &^= ((1 << pointwidth) - 1) end &^= ((1 << pointwidth) - 1) end -= 1 tr, err := qtree.NewReadQTree(q.bs, id, gen) if err != nil { return nil, 0, err } rv, err := tr.QueryStatisticalValuesBlock(start, end, pointwidth) if err != nil { return nil, 0, err } return rv, tr.Generation(), nil }
//Resolution is how far down the tree to go when working out which blocks have changed. Higher resolutions are faster //but will give you back coarser results. func (q *Quasar) QueryChangedRanges(id uuid.UUID, startgen uint64, endgen uint64, resolution uint8) ([]ChangedRange, uint64, error) { //0 is a reserved generation, so is 1, which means "before first" if startgen == 0 { startgen = 1 } tr, err := qtree.NewReadQTree(q.bs, id, endgen) if err != nil { log.Debug("Error on QCR open tree") return nil, 0, err } rv := make([]ChangedRange, 0, 1024) rch := tr.FindChangedSince(startgen, resolution) var lr *ChangedRange = nil for { select { case cr, ok := <-rch: if !ok { //This is the end. //Do we have an unsaved LR? if lr != nil { rv = append(rv, *lr) } return rv, tr.Generation(), nil } if !cr.Valid { log.Panicf("Didn't think this could happen") } //Coalesce if lr != nil && cr.Start == lr.End { lr.End = cr.End } else { if lr != nil { rv = append(rv, *lr) } lr = &ChangedRange{Start: cr.Start, End: cr.End} } } } return rv, tr.Generation(), nil }