github.com/influxdata/influxdb/v2@v2.7.6/influxql/query/iterator.gen.go (about) 1 // Generated by tmpl 2 // https://github.com/benbjohnson/tmpl 3 // 4 // DO NOT EDIT! 5 // Source: iterator.gen.go.tmpl 6 7 //lint:file-ignore U1000 this is generated code 8 package query 9 10 import ( 11 "container/heap" 12 "context" 13 "io" 14 "sort" 15 "sync" 16 "time" 17 18 "github.com/influxdata/influxql" 19 "google.golang.org/protobuf/proto" 20 ) 21 22 // DefaultStatsInterval is the default value for IteratorEncoder.StatsInterval. 23 const DefaultStatsInterval = time.Second 24 25 // FloatIterator represents a stream of float points. 26 type FloatIterator interface { 27 Iterator 28 Next() (*FloatPoint, error) 29 } 30 31 // newFloatIterators converts a slice of Iterator to a slice of FloatIterator. 32 // Drop and closes any iterator in itrs that is not a FloatIterator and cannot 33 // be cast to a FloatIterator. 34 func newFloatIterators(itrs []Iterator) []FloatIterator { 35 a := make([]FloatIterator, 0, len(itrs)) 36 for _, itr := range itrs { 37 switch itr := itr.(type) { 38 case FloatIterator: 39 a = append(a, itr) 40 default: 41 itr.Close() 42 } 43 } 44 return a 45 } 46 47 // bufFloatIterator represents a buffered FloatIterator. 48 type bufFloatIterator struct { 49 itr FloatIterator 50 buf *FloatPoint 51 } 52 53 // newBufFloatIterator returns a buffered FloatIterator. 54 func newBufFloatIterator(itr FloatIterator) *bufFloatIterator { 55 return &bufFloatIterator{itr: itr} 56 } 57 58 // Stats returns statistics from the input iterator. 59 func (itr *bufFloatIterator) Stats() IteratorStats { return itr.itr.Stats() } 60 61 // Close closes the underlying iterator. 62 func (itr *bufFloatIterator) Close() error { return itr.itr.Close() } 63 64 // peek returns the next point without removing it from the iterator. 65 func (itr *bufFloatIterator) peek() (*FloatPoint, error) { 66 p, err := itr.Next() 67 if err != nil { 68 return nil, err 69 } 70 itr.unread(p) 71 return p, nil 72 } 73 74 // peekTime returns the time of the next point. 75 // Returns zero time if no more points available. 76 func (itr *bufFloatIterator) peekTime() (int64, error) { 77 p, err := itr.peek() 78 if p == nil || err != nil { 79 return ZeroTime, err 80 } 81 return p.Time, nil 82 } 83 84 // Next returns the current buffer, if exists, or calls the underlying iterator. 85 func (itr *bufFloatIterator) Next() (*FloatPoint, error) { 86 buf := itr.buf 87 if buf != nil { 88 itr.buf = nil 89 return buf, nil 90 } 91 return itr.itr.Next() 92 } 93 94 // NextInWindow returns the next value if it is between [startTime, endTime). 95 // If the next value is outside the range then it is moved to the buffer. 96 func (itr *bufFloatIterator) NextInWindow(startTime, endTime int64) (*FloatPoint, error) { 97 v, err := itr.Next() 98 if v == nil || err != nil { 99 return nil, err 100 } else if t := v.Time; t >= endTime || t < startTime { 101 itr.unread(v) 102 return nil, nil 103 } 104 return v, nil 105 } 106 107 // unread sets v to the buffer. It is read on the next call to Next(). 108 func (itr *bufFloatIterator) unread(v *FloatPoint) { itr.buf = v } 109 110 // floatMergeIterator represents an iterator that combines multiple float iterators. 111 type floatMergeIterator struct { 112 inputs []FloatIterator 113 heap *floatMergeHeap 114 init bool 115 116 closed bool 117 mu sync.RWMutex 118 119 // Current iterator and window. 120 curr *floatMergeHeapItem 121 window struct { 122 name string 123 tags string 124 startTime int64 125 endTime int64 126 } 127 } 128 129 // newFloatMergeIterator returns a new instance of floatMergeIterator. 130 func newFloatMergeIterator(inputs []FloatIterator, opt IteratorOptions) *floatMergeIterator { 131 itr := &floatMergeIterator{ 132 inputs: inputs, 133 heap: &floatMergeHeap{ 134 items: make([]*floatMergeHeapItem, 0, len(inputs)), 135 opt: opt, 136 }, 137 } 138 139 // Initialize heap items. 140 for _, input := range inputs { 141 // Wrap in buffer, ignore any inputs without anymore points. 142 bufInput := newBufFloatIterator(input) 143 144 // Append to the heap. 145 itr.heap.items = append(itr.heap.items, &floatMergeHeapItem{itr: bufInput}) 146 } 147 148 return itr 149 } 150 151 // Stats returns an aggregation of stats from the underlying iterators. 152 func (itr *floatMergeIterator) Stats() IteratorStats { 153 var stats IteratorStats 154 for _, input := range itr.inputs { 155 stats.Add(input.Stats()) 156 } 157 return stats 158 } 159 160 // Close closes the underlying iterators. 161 func (itr *floatMergeIterator) Close() error { 162 itr.mu.Lock() 163 defer itr.mu.Unlock() 164 165 for _, input := range itr.inputs { 166 input.Close() 167 } 168 itr.curr = nil 169 itr.inputs = nil 170 itr.heap.items = nil 171 itr.closed = true 172 return nil 173 } 174 175 // Next returns the next point from the iterator. 176 func (itr *floatMergeIterator) Next() (*FloatPoint, error) { 177 itr.mu.RLock() 178 defer itr.mu.RUnlock() 179 if itr.closed { 180 return nil, nil 181 } 182 183 // Initialize the heap. This needs to be done lazily on the first call to this iterator 184 // so that iterator initialization done through the Select() call returns quickly. 185 // Queries can only be interrupted after the Select() call completes so any operations 186 // done during iterator creation cannot be interrupted, which is why we do it here 187 // instead so an interrupt can happen while initializing the heap. 188 if !itr.init { 189 items := itr.heap.items 190 itr.heap.items = make([]*floatMergeHeapItem, 0, len(items)) 191 for _, item := range items { 192 if p, err := item.itr.peek(); err != nil { 193 return nil, err 194 } else if p == nil { 195 continue 196 } 197 itr.heap.items = append(itr.heap.items, item) 198 } 199 heap.Init(itr.heap) 200 itr.init = true 201 } 202 203 for { 204 // Retrieve the next iterator if we don't have one. 205 if itr.curr == nil { 206 if len(itr.heap.items) == 0 { 207 return nil, nil 208 } 209 itr.curr = heap.Pop(itr.heap).(*floatMergeHeapItem) 210 211 // Read point and set current window. 212 p, err := itr.curr.itr.Next() 213 if err != nil { 214 return nil, err 215 } 216 tags := p.Tags.Subset(itr.heap.opt.Dimensions) 217 itr.window.name, itr.window.tags = p.Name, tags.ID() 218 itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time) 219 return p, nil 220 } 221 222 // Read the next point from the current iterator. 223 p, err := itr.curr.itr.Next() 224 if err != nil { 225 return nil, err 226 } 227 228 // If there are no more points then remove iterator from heap and find next. 229 if p == nil { 230 itr.curr = nil 231 continue 232 } 233 234 // Check if the point is inside of our current window. 235 inWindow := true 236 if window := itr.window; window.name != p.Name { 237 inWindow = false 238 } else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() { 239 inWindow = false 240 } else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime { 241 inWindow = false 242 } else if !opt.Ascending && p.Time < window.startTime { 243 inWindow = false 244 } 245 246 // If it's outside our window then push iterator back on the heap and find new iterator. 247 if !inWindow { 248 itr.curr.itr.unread(p) 249 heap.Push(itr.heap, itr.curr) 250 itr.curr = nil 251 continue 252 } 253 254 return p, nil 255 } 256 } 257 258 // floatMergeHeap represents a heap of floatMergeHeapItems. 259 // Items are sorted by their next window and then by name/tags. 260 type floatMergeHeap struct { 261 opt IteratorOptions 262 items []*floatMergeHeapItem 263 } 264 265 func (h *floatMergeHeap) Len() int { return len(h.items) } 266 func (h *floatMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] } 267 func (h *floatMergeHeap) Less(i, j int) bool { 268 x, err := h.items[i].itr.peek() 269 if err != nil { 270 return true 271 } 272 y, err := h.items[j].itr.peek() 273 if err != nil { 274 return false 275 } 276 277 if h.opt.Ascending { 278 if x.Name != y.Name { 279 return x.Name < y.Name 280 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() { 281 return xTags.ID() < yTags.ID() 282 } 283 } else { 284 if x.Name != y.Name { 285 return x.Name > y.Name 286 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() { 287 return xTags.ID() > yTags.ID() 288 } 289 } 290 291 xt, _ := h.opt.Window(x.Time) 292 yt, _ := h.opt.Window(y.Time) 293 294 if h.opt.Ascending { 295 return xt < yt 296 } 297 return xt > yt 298 } 299 300 func (h *floatMergeHeap) Push(x interface{}) { 301 h.items = append(h.items, x.(*floatMergeHeapItem)) 302 } 303 304 func (h *floatMergeHeap) Pop() interface{} { 305 old := h.items 306 n := len(old) 307 item := old[n-1] 308 h.items = old[0 : n-1] 309 return item 310 } 311 312 type floatMergeHeapItem struct { 313 itr *bufFloatIterator 314 } 315 316 // floatSortedMergeIterator is an iterator that sorts and merges multiple iterators into one. 317 type floatSortedMergeIterator struct { 318 inputs []FloatIterator 319 heap *floatSortedMergeHeap 320 init bool 321 } 322 323 // newFloatSortedMergeIterator returns an instance of floatSortedMergeIterator. 324 func newFloatSortedMergeIterator(inputs []FloatIterator, opt IteratorOptions) Iterator { 325 itr := &floatSortedMergeIterator{ 326 inputs: inputs, 327 heap: &floatSortedMergeHeap{ 328 items: make([]*floatSortedMergeHeapItem, 0, len(inputs)), 329 opt: opt, 330 }, 331 } 332 333 // Initialize heap items. 334 for _, input := range inputs { 335 // Append to the heap. 336 itr.heap.items = append(itr.heap.items, &floatSortedMergeHeapItem{itr: input}) 337 } 338 339 return itr 340 } 341 342 // Stats returns an aggregation of stats from the underlying iterators. 343 func (itr *floatSortedMergeIterator) Stats() IteratorStats { 344 var stats IteratorStats 345 for _, input := range itr.inputs { 346 stats.Add(input.Stats()) 347 } 348 return stats 349 } 350 351 // Close closes the underlying iterators. 352 func (itr *floatSortedMergeIterator) Close() error { 353 for _, input := range itr.inputs { 354 input.Close() 355 } 356 return nil 357 } 358 359 // Next returns the next points from the iterator. 360 func (itr *floatSortedMergeIterator) Next() (*FloatPoint, error) { return itr.pop() } 361 362 // pop returns the next point from the heap. 363 // Reads the next point from item's cursor and puts it back on the heap. 364 func (itr *floatSortedMergeIterator) pop() (*FloatPoint, error) { 365 // Initialize the heap. See the MergeIterator to see why this has to be done lazily. 366 if !itr.init { 367 items := itr.heap.items 368 itr.heap.items = make([]*floatSortedMergeHeapItem, 0, len(items)) 369 for _, item := range items { 370 var err error 371 if item.point, err = item.itr.Next(); err != nil { 372 return nil, err 373 } else if item.point == nil { 374 continue 375 } 376 itr.heap.items = append(itr.heap.items, item) 377 } 378 heap.Init(itr.heap) 379 itr.init = true 380 } 381 382 if len(itr.heap.items) == 0 { 383 return nil, nil 384 } 385 386 // Read the next item from the heap. 387 item := heap.Pop(itr.heap).(*floatSortedMergeHeapItem) 388 if item.err != nil { 389 return nil, item.err 390 } else if item.point == nil { 391 return nil, nil 392 } 393 394 // Copy the point for return. 395 p := item.point.Clone() 396 397 // Read the next item from the cursor. Push back to heap if one exists. 398 if item.point, item.err = item.itr.Next(); item.point != nil { 399 heap.Push(itr.heap, item) 400 } 401 402 return p, nil 403 } 404 405 // floatSortedMergeHeap represents a heap of floatSortedMergeHeapItems. 406 // Items are sorted with the following priority: 407 // - By their measurement name; 408 // - By their tag keys/values; 409 // - By time; or 410 // - By their Aux field values. 411 type floatSortedMergeHeap struct { 412 opt IteratorOptions 413 items []*floatSortedMergeHeapItem 414 } 415 416 func (h *floatSortedMergeHeap) Len() int { return len(h.items) } 417 func (h *floatSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] } 418 func (h *floatSortedMergeHeap) Less(i, j int) bool { 419 x, y := h.items[i].point, h.items[j].point 420 421 if h.opt.Ascending { 422 if x.Name != y.Name { 423 return x.Name < y.Name 424 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) { 425 return xTags.ID() < yTags.ID() 426 } 427 428 if x.Time != y.Time { 429 return x.Time < y.Time 430 } 431 432 if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) { 433 for i := 0; i < len(x.Aux); i++ { 434 v1, ok1 := x.Aux[i].(string) 435 v2, ok2 := y.Aux[i].(string) 436 if !ok1 || !ok2 { 437 // Unsupported types used in Aux fields. Maybe they 438 // need to be added here? 439 return false 440 } else if v1 == v2 { 441 continue 442 } 443 return v1 < v2 444 } 445 } 446 return false // Times and/or Aux fields are equal. 447 } 448 449 if x.Name != y.Name { 450 return x.Name > y.Name 451 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) { 452 return xTags.ID() > yTags.ID() 453 } 454 455 if x.Time != y.Time { 456 return x.Time > y.Time 457 } 458 459 if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) { 460 for i := 0; i < len(x.Aux); i++ { 461 v1, ok1 := x.Aux[i].(string) 462 v2, ok2 := y.Aux[i].(string) 463 if !ok1 || !ok2 { 464 // Unsupported types used in Aux fields. Maybe they 465 // need to be added here? 466 return false 467 } else if v1 == v2 { 468 continue 469 } 470 return v1 > v2 471 } 472 } 473 return false // Times and/or Aux fields are equal. 474 } 475 476 func (h *floatSortedMergeHeap) Push(x interface{}) { 477 h.items = append(h.items, x.(*floatSortedMergeHeapItem)) 478 } 479 480 func (h *floatSortedMergeHeap) Pop() interface{} { 481 old := h.items 482 n := len(old) 483 item := old[n-1] 484 h.items = old[0 : n-1] 485 return item 486 } 487 488 type floatSortedMergeHeapItem struct { 489 point *FloatPoint 490 err error 491 itr FloatIterator 492 } 493 494 // floatIteratorScanner scans the results of a FloatIterator into a map. 495 type floatIteratorScanner struct { 496 input *bufFloatIterator 497 err error 498 keys []influxql.VarRef 499 defaultValue interface{} 500 } 501 502 // newFloatIteratorScanner creates a new IteratorScanner. 503 func newFloatIteratorScanner(input FloatIterator, keys []influxql.VarRef, defaultValue interface{}) *floatIteratorScanner { 504 return &floatIteratorScanner{ 505 input: newBufFloatIterator(input), 506 keys: keys, 507 defaultValue: defaultValue, 508 } 509 } 510 511 func (s *floatIteratorScanner) Peek() (int64, string, Tags) { 512 if s.err != nil { 513 return ZeroTime, "", Tags{} 514 } 515 516 p, err := s.input.peek() 517 if err != nil { 518 s.err = err 519 return ZeroTime, "", Tags{} 520 } else if p == nil { 521 return ZeroTime, "", Tags{} 522 } 523 return p.Time, p.Name, p.Tags 524 } 525 526 func (s *floatIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) { 527 if s.err != nil { 528 return 529 } 530 531 p, err := s.input.Next() 532 if err != nil { 533 s.err = err 534 return 535 } else if p == nil { 536 s.useDefaults(m) 537 return 538 } else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) { 539 s.useDefaults(m) 540 s.input.unread(p) 541 return 542 } 543 544 if k := s.keys[0]; k.Val != "" { 545 if p.Nil { 546 if s.defaultValue != SkipDefault { 547 m[k.Val] = castToType(s.defaultValue, k.Type) 548 } 549 } else { 550 m[k.Val] = p.Value 551 } 552 } 553 for i, v := range p.Aux { 554 k := s.keys[i+1] 555 switch v.(type) { 556 case float64, int64, uint64, string, bool: 557 m[k.Val] = v 558 default: 559 // Insert the fill value if one was specified. 560 if s.defaultValue != SkipDefault { 561 m[k.Val] = castToType(s.defaultValue, k.Type) 562 } 563 } 564 } 565 } 566 567 func (s *floatIteratorScanner) useDefaults(m map[string]interface{}) { 568 if s.defaultValue == SkipDefault { 569 return 570 } 571 for _, k := range s.keys { 572 if k.Val == "" { 573 continue 574 } 575 m[k.Val] = castToType(s.defaultValue, k.Type) 576 } 577 } 578 579 func (s *floatIteratorScanner) Stats() IteratorStats { return s.input.Stats() } 580 func (s *floatIteratorScanner) Err() error { return s.err } 581 func (s *floatIteratorScanner) Close() error { return s.input.Close() } 582 583 // floatParallelIterator represents an iterator that pulls data in a separate goroutine. 584 type floatParallelIterator struct { 585 input FloatIterator 586 ch chan floatPointError 587 588 once sync.Once 589 closing chan struct{} 590 wg sync.WaitGroup 591 } 592 593 // newFloatParallelIterator returns a new instance of floatParallelIterator. 594 func newFloatParallelIterator(input FloatIterator) *floatParallelIterator { 595 itr := &floatParallelIterator{ 596 input: input, 597 ch: make(chan floatPointError, 256), 598 closing: make(chan struct{}), 599 } 600 itr.wg.Add(1) 601 go itr.monitor() 602 return itr 603 } 604 605 // Stats returns stats from the underlying iterator. 606 func (itr *floatParallelIterator) Stats() IteratorStats { return itr.input.Stats() } 607 608 // Close closes the underlying iterators. 609 func (itr *floatParallelIterator) Close() error { 610 itr.once.Do(func() { close(itr.closing) }) 611 itr.wg.Wait() 612 return itr.input.Close() 613 } 614 615 // Next returns the next point from the iterator. 616 func (itr *floatParallelIterator) Next() (*FloatPoint, error) { 617 v, ok := <-itr.ch 618 if !ok { 619 return nil, io.EOF 620 } 621 return v.point, v.err 622 } 623 624 // monitor runs in a separate goroutine and actively pulls the next point. 625 func (itr *floatParallelIterator) monitor() { 626 defer close(itr.ch) 627 defer itr.wg.Done() 628 629 for { 630 // Read next point. 631 p, err := itr.input.Next() 632 if p != nil { 633 p = p.Clone() 634 } 635 636 select { 637 case <-itr.closing: 638 return 639 case itr.ch <- floatPointError{point: p, err: err}: 640 } 641 } 642 } 643 644 type floatPointError struct { 645 point *FloatPoint 646 err error 647 } 648 649 // floatLimitIterator represents an iterator that limits points per group. 650 type floatLimitIterator struct { 651 input FloatIterator 652 opt IteratorOptions 653 n int 654 655 prev struct { 656 name string 657 tags Tags 658 } 659 } 660 661 // newFloatLimitIterator returns a new instance of floatLimitIterator. 662 func newFloatLimitIterator(input FloatIterator, opt IteratorOptions) *floatLimitIterator { 663 return &floatLimitIterator{ 664 input: input, 665 opt: opt, 666 } 667 } 668 669 // Stats returns stats from the underlying iterator. 670 func (itr *floatLimitIterator) Stats() IteratorStats { return itr.input.Stats() } 671 672 // Close closes the underlying iterators. 673 func (itr *floatLimitIterator) Close() error { return itr.input.Close() } 674 675 // Next returns the next point from the iterator. 676 func (itr *floatLimitIterator) Next() (*FloatPoint, error) { 677 for { 678 p, err := itr.input.Next() 679 if p == nil || err != nil { 680 return nil, err 681 } 682 683 // Reset window and counter if a new window is encountered. 684 if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) { 685 itr.prev.name = p.Name 686 itr.prev.tags = p.Tags 687 itr.n = 0 688 } 689 690 // Increment counter. 691 itr.n++ 692 693 // Read next point if not beyond the offset. 694 if itr.n <= itr.opt.Offset { 695 continue 696 } 697 698 // Read next point if we're beyond the limit. 699 if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit { 700 continue 701 } 702 703 return p, nil 704 } 705 } 706 707 type floatFillIterator struct { 708 input *bufFloatIterator 709 prev FloatPoint 710 startTime int64 711 endTime int64 712 auxFields []interface{} 713 init bool 714 opt IteratorOptions 715 716 window struct { 717 name string 718 tags Tags 719 time int64 720 offset int64 721 } 722 } 723 724 func newFloatFillIterator(input FloatIterator, expr influxql.Expr, opt IteratorOptions) *floatFillIterator { 725 if opt.Fill == influxql.NullFill { 726 if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" { 727 opt.Fill = influxql.NumberFill 728 opt.FillValue = float64(0) 729 } 730 } 731 732 var startTime, endTime int64 733 if opt.Ascending { 734 startTime, _ = opt.Window(opt.StartTime) 735 endTime, _ = opt.Window(opt.EndTime) 736 } else { 737 startTime, _ = opt.Window(opt.EndTime) 738 endTime, _ = opt.Window(opt.StartTime) 739 } 740 741 var auxFields []interface{} 742 if len(opt.Aux) > 0 { 743 auxFields = make([]interface{}, len(opt.Aux)) 744 } 745 746 return &floatFillIterator{ 747 input: newBufFloatIterator(input), 748 prev: FloatPoint{Nil: true}, 749 startTime: startTime, 750 endTime: endTime, 751 auxFields: auxFields, 752 opt: opt, 753 } 754 } 755 756 func (itr *floatFillIterator) Stats() IteratorStats { return itr.input.Stats() } 757 func (itr *floatFillIterator) Close() error { return itr.input.Close() } 758 759 func (itr *floatFillIterator) Next() (*FloatPoint, error) { 760 if !itr.init { 761 p, err := itr.input.peek() 762 if p == nil || err != nil { 763 return nil, err 764 } 765 itr.window.name, itr.window.tags = p.Name, p.Tags 766 itr.window.time = itr.startTime 767 if itr.startTime == influxql.MinTime { 768 itr.window.time, _ = itr.opt.Window(p.Time) 769 } 770 if itr.opt.Location != nil { 771 _, itr.window.offset = itr.opt.Zone(itr.window.time) 772 } 773 itr.init = true 774 } 775 776 p, err := itr.input.Next() 777 if err != nil { 778 return nil, err 779 } 780 781 // Check if the next point is outside of our window or is nil. 782 if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() { 783 // If we are inside of an interval, unread the point and continue below to 784 // constructing a new point. 785 if itr.opt.Ascending && itr.window.time <= itr.endTime { 786 itr.input.unread(p) 787 p = nil 788 goto CONSTRUCT 789 } else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime { 790 itr.input.unread(p) 791 p = nil 792 goto CONSTRUCT 793 } 794 795 // We are *not* in a current interval. If there is no next point, 796 // we are at the end of all intervals. 797 if p == nil { 798 return nil, nil 799 } 800 801 // Set the new interval. 802 itr.window.name, itr.window.tags = p.Name, p.Tags 803 itr.window.time = itr.startTime 804 if itr.window.time == influxql.MinTime { 805 itr.window.time, _ = itr.opt.Window(p.Time) 806 } 807 if itr.opt.Location != nil { 808 _, itr.window.offset = itr.opt.Zone(itr.window.time) 809 } 810 itr.prev = FloatPoint{Nil: true} 811 } 812 813 // Check if the point is our next expected point. 814 CONSTRUCT: 815 if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) { 816 if p != nil { 817 itr.input.unread(p) 818 } 819 820 p = &FloatPoint{ 821 Name: itr.window.name, 822 Tags: itr.window.tags, 823 Time: itr.window.time, 824 Aux: itr.auxFields, 825 } 826 827 switch itr.opt.Fill { 828 case influxql.LinearFill: 829 if !itr.prev.Nil { 830 next, err := itr.input.peek() 831 if err != nil { 832 return nil, err 833 } else if next != nil && next.Name == itr.window.name && next.Tags.ID() == itr.window.tags.ID() { 834 interval := int64(itr.opt.Interval.Duration) 835 start := itr.window.time / interval 836 p.Value = linearFloat(start, itr.prev.Time/interval, next.Time/interval, itr.prev.Value, next.Value) 837 } else { 838 p.Nil = true 839 } 840 } else { 841 p.Nil = true 842 } 843 844 case influxql.NullFill: 845 p.Nil = true 846 case influxql.NumberFill: 847 p.Value, _ = castToFloat(itr.opt.FillValue) 848 case influxql.PreviousFill: 849 if !itr.prev.Nil { 850 p.Value = itr.prev.Value 851 p.Nil = itr.prev.Nil 852 } else { 853 p.Nil = true 854 } 855 } 856 } else { 857 itr.prev = *p 858 } 859 860 // Advance the expected time. Do not advance to a new window here 861 // as there may be lingering points with the same timestamp in the previous 862 // window. 863 if itr.opt.Ascending { 864 itr.window.time += int64(itr.opt.Interval.Duration) 865 } else { 866 itr.window.time -= int64(itr.opt.Interval.Duration) 867 } 868 869 // Check to see if we have passed over an offset change and adjust the time 870 // to account for this new offset. 871 if itr.opt.Location != nil { 872 if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset { 873 diff := itr.window.offset - offset 874 if abs(diff) < int64(itr.opt.Interval.Duration) { 875 itr.window.time += diff 876 } 877 itr.window.offset = offset 878 } 879 } 880 return p, nil 881 } 882 883 // floatIntervalIterator represents a float implementation of IntervalIterator. 884 type floatIntervalIterator struct { 885 input FloatIterator 886 opt IteratorOptions 887 } 888 889 func newFloatIntervalIterator(input FloatIterator, opt IteratorOptions) *floatIntervalIterator { 890 return &floatIntervalIterator{input: input, opt: opt} 891 } 892 893 func (itr *floatIntervalIterator) Stats() IteratorStats { return itr.input.Stats() } 894 func (itr *floatIntervalIterator) Close() error { return itr.input.Close() } 895 896 func (itr *floatIntervalIterator) Next() (*FloatPoint, error) { 897 p, err := itr.input.Next() 898 if p == nil || err != nil { 899 return nil, err 900 } 901 p.Time, _ = itr.opt.Window(p.Time) 902 // If we see the minimum allowable time, set the time to zero so we don't 903 // break the default returned time for aggregate queries without times. 904 if p.Time == influxql.MinTime { 905 p.Time = 0 906 } 907 return p, nil 908 } 909 910 // floatInterruptIterator represents a float implementation of InterruptIterator. 911 type floatInterruptIterator struct { 912 input FloatIterator 913 closing <-chan struct{} 914 count int 915 } 916 917 func newFloatInterruptIterator(input FloatIterator, closing <-chan struct{}) *floatInterruptIterator { 918 return &floatInterruptIterator{input: input, closing: closing} 919 } 920 921 func (itr *floatInterruptIterator) Stats() IteratorStats { return itr.input.Stats() } 922 func (itr *floatInterruptIterator) Close() error { return itr.input.Close() } 923 924 func (itr *floatInterruptIterator) Next() (*FloatPoint, error) { 925 // Only check if the channel is closed every N points. This 926 // intentionally checks on both 0 and N so that if the iterator 927 // has been interrupted before the first point is emitted it will 928 // not emit any points. 929 if itr.count&0xFF == 0xFF { 930 select { 931 case <-itr.closing: 932 return nil, itr.Close() 933 default: 934 // Reset iterator count to zero and fall through to emit the next point. 935 itr.count = 0 936 } 937 } 938 939 // Increment the counter for every point read. 940 itr.count++ 941 return itr.input.Next() 942 } 943 944 // floatCloseInterruptIterator represents a float implementation of CloseInterruptIterator. 945 type floatCloseInterruptIterator struct { 946 input FloatIterator 947 closing <-chan struct{} 948 done chan struct{} 949 once sync.Once 950 } 951 952 func newFloatCloseInterruptIterator(input FloatIterator, closing <-chan struct{}) *floatCloseInterruptIterator { 953 itr := &floatCloseInterruptIterator{ 954 input: input, 955 closing: closing, 956 done: make(chan struct{}), 957 } 958 go itr.monitor() 959 return itr 960 } 961 962 func (itr *floatCloseInterruptIterator) monitor() { 963 select { 964 case <-itr.closing: 965 itr.Close() 966 case <-itr.done: 967 } 968 } 969 970 func (itr *floatCloseInterruptIterator) Stats() IteratorStats { 971 return itr.input.Stats() 972 } 973 974 func (itr *floatCloseInterruptIterator) Close() error { 975 itr.once.Do(func() { 976 close(itr.done) 977 itr.input.Close() 978 }) 979 return nil 980 } 981 982 func (itr *floatCloseInterruptIterator) Next() (*FloatPoint, error) { 983 p, err := itr.input.Next() 984 if err != nil { 985 // Check if the iterator was closed. 986 select { 987 case <-itr.done: 988 return nil, nil 989 default: 990 return nil, err 991 } 992 } 993 return p, nil 994 } 995 996 // floatReduceFloatIterator executes a reducer for every interval and buffers the result. 997 type floatReduceFloatIterator struct { 998 input *bufFloatIterator 999 create func() (FloatPointAggregator, FloatPointEmitter) 1000 dims []string 1001 opt IteratorOptions 1002 points []FloatPoint 1003 keepTags bool 1004 } 1005 1006 func newFloatReduceFloatIterator(input FloatIterator, opt IteratorOptions, createFn func() (FloatPointAggregator, FloatPointEmitter)) *floatReduceFloatIterator { 1007 return &floatReduceFloatIterator{ 1008 input: newBufFloatIterator(input), 1009 create: createFn, 1010 dims: opt.GetDimensions(), 1011 opt: opt, 1012 } 1013 } 1014 1015 // Stats returns stats from the input iterator. 1016 func (itr *floatReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() } 1017 1018 // Close closes the iterator and all child iterators. 1019 func (itr *floatReduceFloatIterator) Close() error { return itr.input.Close() } 1020 1021 // Next returns the minimum value for the next available interval. 1022 func (itr *floatReduceFloatIterator) Next() (*FloatPoint, error) { 1023 // Calculate next window if we have no more points. 1024 if len(itr.points) == 0 { 1025 var err error 1026 itr.points, err = itr.reduce() 1027 if len(itr.points) == 0 { 1028 return nil, err 1029 } 1030 } 1031 1032 // Pop next point off the stack. 1033 p := &itr.points[len(itr.points)-1] 1034 itr.points = itr.points[:len(itr.points)-1] 1035 return p, nil 1036 } 1037 1038 // floatReduceFloatPoint stores the reduced data for a name/tag combination. 1039 type floatReduceFloatPoint struct { 1040 Name string 1041 Tags Tags 1042 Aggregator FloatPointAggregator 1043 Emitter FloatPointEmitter 1044 } 1045 1046 // reduce executes fn once for every point in the next window. 1047 // The previous value for the dimension is passed to fn. 1048 func (itr *floatReduceFloatIterator) reduce() ([]FloatPoint, error) { 1049 // Calculate next window. 1050 var ( 1051 startTime, endTime int64 1052 window struct { 1053 name string 1054 tags string 1055 } 1056 ) 1057 for { 1058 p, err := itr.input.Next() 1059 if err != nil || p == nil { 1060 return nil, err 1061 } else if p.Nil { 1062 continue 1063 } 1064 1065 // Unread the point so it can be processed. 1066 itr.input.unread(p) 1067 startTime, endTime = itr.opt.Window(p.Time) 1068 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 1069 break 1070 } 1071 1072 // Create points by tags. 1073 m := make(map[string]*floatReduceFloatPoint) 1074 for { 1075 // Read next point. 1076 curr, err := itr.input.NextInWindow(startTime, endTime) 1077 if err != nil { 1078 return nil, err 1079 } else if curr == nil { 1080 break 1081 } else if curr.Nil { 1082 continue 1083 } else if curr.Name != window.name { 1084 itr.input.unread(curr) 1085 break 1086 } 1087 1088 // Ensure this point is within the same final window. 1089 if curr.Name != window.name { 1090 itr.input.unread(curr) 1091 break 1092 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 1093 itr.input.unread(curr) 1094 break 1095 } 1096 1097 // Retrieve the tags on this point for this level of the query. 1098 // This may be different than the bucket dimensions. 1099 tags := curr.Tags.Subset(itr.dims) 1100 id := tags.ID() 1101 1102 // Retrieve the aggregator for this name/tag combination or create one. 1103 rp := m[id] 1104 if rp == nil { 1105 aggregator, emitter := itr.create() 1106 rp = &floatReduceFloatPoint{ 1107 Name: curr.Name, 1108 Tags: tags, 1109 Aggregator: aggregator, 1110 Emitter: emitter, 1111 } 1112 m[id] = rp 1113 } 1114 rp.Aggregator.AggregateFloat(curr) 1115 } 1116 1117 keys := make([]string, 0, len(m)) 1118 for k := range m { 1119 keys = append(keys, k) 1120 } 1121 1122 // Reverse sort points by name & tag. 1123 // This ensures a consistent order of output. 1124 if len(keys) > 0 { 1125 var sorted sort.Interface = sort.StringSlice(keys) 1126 if itr.opt.Ascending { 1127 sorted = sort.Reverse(sorted) 1128 } 1129 sort.Sort(sorted) 1130 } 1131 1132 // Assume the points are already sorted until proven otherwise. 1133 sortedByTime := true 1134 // Emit the points for each name & tag combination. 1135 a := make([]FloatPoint, 0, len(m)) 1136 for _, k := range keys { 1137 rp := m[k] 1138 points := rp.Emitter.Emit() 1139 for i := len(points) - 1; i >= 0; i-- { 1140 points[i].Name = rp.Name 1141 if !itr.keepTags { 1142 points[i].Tags = rp.Tags 1143 } 1144 // Set the points time to the interval time if the reducer didn't provide one. 1145 if points[i].Time == ZeroTime { 1146 points[i].Time = startTime 1147 } else { 1148 sortedByTime = false 1149 } 1150 a = append(a, points[i]) 1151 } 1152 } 1153 // Points may be out of order. Perform a stable sort by time if requested. 1154 if !sortedByTime && itr.opt.Ordered { 1155 var sorted sort.Interface = floatPointsByTime(a) 1156 if itr.opt.Ascending { 1157 sorted = sort.Reverse(sorted) 1158 } 1159 sort.Stable(sorted) 1160 } 1161 return a, nil 1162 } 1163 1164 // floatStreamFloatIterator streams inputs into the iterator and emits points gradually. 1165 type floatStreamFloatIterator struct { 1166 input *bufFloatIterator 1167 create func() (FloatPointAggregator, FloatPointEmitter) 1168 dims []string 1169 opt IteratorOptions 1170 m map[string]*floatReduceFloatPoint 1171 points []FloatPoint 1172 } 1173 1174 // newFloatStreamFloatIterator returns a new instance of floatStreamFloatIterator. 1175 func newFloatStreamFloatIterator(input FloatIterator, createFn func() (FloatPointAggregator, FloatPointEmitter), opt IteratorOptions) *floatStreamFloatIterator { 1176 return &floatStreamFloatIterator{ 1177 input: newBufFloatIterator(input), 1178 create: createFn, 1179 dims: opt.GetDimensions(), 1180 opt: opt, 1181 m: make(map[string]*floatReduceFloatPoint), 1182 } 1183 } 1184 1185 // Stats returns stats from the input iterator. 1186 func (itr *floatStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() } 1187 1188 // Close closes the iterator and all child iterators. 1189 func (itr *floatStreamFloatIterator) Close() error { return itr.input.Close() } 1190 1191 // Next returns the next value for the stream iterator. 1192 func (itr *floatStreamFloatIterator) Next() (*FloatPoint, error) { 1193 // Calculate next window if we have no more points. 1194 if len(itr.points) == 0 { 1195 var err error 1196 itr.points, err = itr.reduce() 1197 if len(itr.points) == 0 { 1198 return nil, err 1199 } 1200 } 1201 1202 // Pop next point off the stack. 1203 p := &itr.points[len(itr.points)-1] 1204 itr.points = itr.points[:len(itr.points)-1] 1205 return p, nil 1206 } 1207 1208 // reduce creates and manages aggregators for every point from the input. 1209 // After aggregating a point, it always tries to emit a value using the emitter. 1210 func (itr *floatStreamFloatIterator) reduce() ([]FloatPoint, error) { 1211 // We have already read all of the input points. 1212 if itr.m == nil { 1213 return nil, nil 1214 } 1215 1216 for { 1217 // Read next point. 1218 curr, err := itr.input.Next() 1219 if err != nil { 1220 return nil, err 1221 } else if curr == nil { 1222 // Close all of the aggregators to flush any remaining points to emit. 1223 var points []FloatPoint 1224 for _, rp := range itr.m { 1225 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 1226 if err := aggregator.Close(); err != nil { 1227 return nil, err 1228 } 1229 1230 pts := rp.Emitter.Emit() 1231 if len(pts) == 0 { 1232 continue 1233 } 1234 1235 for i := range pts { 1236 pts[i].Name = rp.Name 1237 pts[i].Tags = rp.Tags 1238 } 1239 points = append(points, pts...) 1240 } 1241 } 1242 1243 // Eliminate the aggregators and emitters. 1244 itr.m = nil 1245 return points, nil 1246 } else if curr.Nil { 1247 continue 1248 } 1249 tags := curr.Tags.Subset(itr.dims) 1250 1251 id := curr.Name 1252 if len(tags.m) > 0 { 1253 id += "\x00" + tags.ID() 1254 } 1255 1256 // Retrieve the aggregator for this name/tag combination or create one. 1257 rp := itr.m[id] 1258 if rp == nil { 1259 aggregator, emitter := itr.create() 1260 rp = &floatReduceFloatPoint{ 1261 Name: curr.Name, 1262 Tags: tags, 1263 Aggregator: aggregator, 1264 Emitter: emitter, 1265 } 1266 itr.m[id] = rp 1267 } 1268 rp.Aggregator.AggregateFloat(curr) 1269 1270 // Attempt to emit points from the aggregator. 1271 points := rp.Emitter.Emit() 1272 if len(points) == 0 { 1273 continue 1274 } 1275 1276 for i := range points { 1277 points[i].Name = rp.Name 1278 points[i].Tags = rp.Tags 1279 } 1280 return points, nil 1281 } 1282 } 1283 1284 // floatReduceIntegerIterator executes a reducer for every interval and buffers the result. 1285 type floatReduceIntegerIterator struct { 1286 input *bufFloatIterator 1287 create func() (FloatPointAggregator, IntegerPointEmitter) 1288 dims []string 1289 opt IteratorOptions 1290 points []IntegerPoint 1291 keepTags bool 1292 } 1293 1294 func newFloatReduceIntegerIterator(input FloatIterator, opt IteratorOptions, createFn func() (FloatPointAggregator, IntegerPointEmitter)) *floatReduceIntegerIterator { 1295 return &floatReduceIntegerIterator{ 1296 input: newBufFloatIterator(input), 1297 create: createFn, 1298 dims: opt.GetDimensions(), 1299 opt: opt, 1300 } 1301 } 1302 1303 // Stats returns stats from the input iterator. 1304 func (itr *floatReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() } 1305 1306 // Close closes the iterator and all child iterators. 1307 func (itr *floatReduceIntegerIterator) Close() error { return itr.input.Close() } 1308 1309 // Next returns the minimum value for the next available interval. 1310 func (itr *floatReduceIntegerIterator) Next() (*IntegerPoint, error) { 1311 // Calculate next window if we have no more points. 1312 if len(itr.points) == 0 { 1313 var err error 1314 itr.points, err = itr.reduce() 1315 if len(itr.points) == 0 { 1316 return nil, err 1317 } 1318 } 1319 1320 // Pop next point off the stack. 1321 p := &itr.points[len(itr.points)-1] 1322 itr.points = itr.points[:len(itr.points)-1] 1323 return p, nil 1324 } 1325 1326 // floatReduceIntegerPoint stores the reduced data for a name/tag combination. 1327 type floatReduceIntegerPoint struct { 1328 Name string 1329 Tags Tags 1330 Aggregator FloatPointAggregator 1331 Emitter IntegerPointEmitter 1332 } 1333 1334 // reduce executes fn once for every point in the next window. 1335 // The previous value for the dimension is passed to fn. 1336 func (itr *floatReduceIntegerIterator) reduce() ([]IntegerPoint, error) { 1337 // Calculate next window. 1338 var ( 1339 startTime, endTime int64 1340 window struct { 1341 name string 1342 tags string 1343 } 1344 ) 1345 for { 1346 p, err := itr.input.Next() 1347 if err != nil || p == nil { 1348 return nil, err 1349 } else if p.Nil { 1350 continue 1351 } 1352 1353 // Unread the point so it can be processed. 1354 itr.input.unread(p) 1355 startTime, endTime = itr.opt.Window(p.Time) 1356 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 1357 break 1358 } 1359 1360 // Create points by tags. 1361 m := make(map[string]*floatReduceIntegerPoint) 1362 for { 1363 // Read next point. 1364 curr, err := itr.input.NextInWindow(startTime, endTime) 1365 if err != nil { 1366 return nil, err 1367 } else if curr == nil { 1368 break 1369 } else if curr.Nil { 1370 continue 1371 } else if curr.Name != window.name { 1372 itr.input.unread(curr) 1373 break 1374 } 1375 1376 // Ensure this point is within the same final window. 1377 if curr.Name != window.name { 1378 itr.input.unread(curr) 1379 break 1380 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 1381 itr.input.unread(curr) 1382 break 1383 } 1384 1385 // Retrieve the tags on this point for this level of the query. 1386 // This may be different than the bucket dimensions. 1387 tags := curr.Tags.Subset(itr.dims) 1388 id := tags.ID() 1389 1390 // Retrieve the aggregator for this name/tag combination or create one. 1391 rp := m[id] 1392 if rp == nil { 1393 aggregator, emitter := itr.create() 1394 rp = &floatReduceIntegerPoint{ 1395 Name: curr.Name, 1396 Tags: tags, 1397 Aggregator: aggregator, 1398 Emitter: emitter, 1399 } 1400 m[id] = rp 1401 } 1402 rp.Aggregator.AggregateFloat(curr) 1403 } 1404 1405 keys := make([]string, 0, len(m)) 1406 for k := range m { 1407 keys = append(keys, k) 1408 } 1409 1410 // Reverse sort points by name & tag. 1411 // This ensures a consistent order of output. 1412 if len(keys) > 0 { 1413 var sorted sort.Interface = sort.StringSlice(keys) 1414 if itr.opt.Ascending { 1415 sorted = sort.Reverse(sorted) 1416 } 1417 sort.Sort(sorted) 1418 } 1419 1420 // Assume the points are already sorted until proven otherwise. 1421 sortedByTime := true 1422 // Emit the points for each name & tag combination. 1423 a := make([]IntegerPoint, 0, len(m)) 1424 for _, k := range keys { 1425 rp := m[k] 1426 points := rp.Emitter.Emit() 1427 for i := len(points) - 1; i >= 0; i-- { 1428 points[i].Name = rp.Name 1429 if !itr.keepTags { 1430 points[i].Tags = rp.Tags 1431 } 1432 // Set the points time to the interval time if the reducer didn't provide one. 1433 if points[i].Time == ZeroTime { 1434 points[i].Time = startTime 1435 } else { 1436 sortedByTime = false 1437 } 1438 a = append(a, points[i]) 1439 } 1440 } 1441 // Points may be out of order. Perform a stable sort by time if requested. 1442 if !sortedByTime && itr.opt.Ordered { 1443 var sorted sort.Interface = integerPointsByTime(a) 1444 if itr.opt.Ascending { 1445 sorted = sort.Reverse(sorted) 1446 } 1447 sort.Stable(sorted) 1448 } 1449 return a, nil 1450 } 1451 1452 // floatStreamIntegerIterator streams inputs into the iterator and emits points gradually. 1453 type floatStreamIntegerIterator struct { 1454 input *bufFloatIterator 1455 create func() (FloatPointAggregator, IntegerPointEmitter) 1456 dims []string 1457 opt IteratorOptions 1458 m map[string]*floatReduceIntegerPoint 1459 points []IntegerPoint 1460 } 1461 1462 // newFloatStreamIntegerIterator returns a new instance of floatStreamIntegerIterator. 1463 func newFloatStreamIntegerIterator(input FloatIterator, createFn func() (FloatPointAggregator, IntegerPointEmitter), opt IteratorOptions) *floatStreamIntegerIterator { 1464 return &floatStreamIntegerIterator{ 1465 input: newBufFloatIterator(input), 1466 create: createFn, 1467 dims: opt.GetDimensions(), 1468 opt: opt, 1469 m: make(map[string]*floatReduceIntegerPoint), 1470 } 1471 } 1472 1473 // Stats returns stats from the input iterator. 1474 func (itr *floatStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() } 1475 1476 // Close closes the iterator and all child iterators. 1477 func (itr *floatStreamIntegerIterator) Close() error { return itr.input.Close() } 1478 1479 // Next returns the next value for the stream iterator. 1480 func (itr *floatStreamIntegerIterator) Next() (*IntegerPoint, error) { 1481 // Calculate next window if we have no more points. 1482 if len(itr.points) == 0 { 1483 var err error 1484 itr.points, err = itr.reduce() 1485 if len(itr.points) == 0 { 1486 return nil, err 1487 } 1488 } 1489 1490 // Pop next point off the stack. 1491 p := &itr.points[len(itr.points)-1] 1492 itr.points = itr.points[:len(itr.points)-1] 1493 return p, nil 1494 } 1495 1496 // reduce creates and manages aggregators for every point from the input. 1497 // After aggregating a point, it always tries to emit a value using the emitter. 1498 func (itr *floatStreamIntegerIterator) reduce() ([]IntegerPoint, error) { 1499 // We have already read all of the input points. 1500 if itr.m == nil { 1501 return nil, nil 1502 } 1503 1504 for { 1505 // Read next point. 1506 curr, err := itr.input.Next() 1507 if err != nil { 1508 return nil, err 1509 } else if curr == nil { 1510 // Close all of the aggregators to flush any remaining points to emit. 1511 var points []IntegerPoint 1512 for _, rp := range itr.m { 1513 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 1514 if err := aggregator.Close(); err != nil { 1515 return nil, err 1516 } 1517 1518 pts := rp.Emitter.Emit() 1519 if len(pts) == 0 { 1520 continue 1521 } 1522 1523 for i := range pts { 1524 pts[i].Name = rp.Name 1525 pts[i].Tags = rp.Tags 1526 } 1527 points = append(points, pts...) 1528 } 1529 } 1530 1531 // Eliminate the aggregators and emitters. 1532 itr.m = nil 1533 return points, nil 1534 } else if curr.Nil { 1535 continue 1536 } 1537 tags := curr.Tags.Subset(itr.dims) 1538 1539 id := curr.Name 1540 if len(tags.m) > 0 { 1541 id += "\x00" + tags.ID() 1542 } 1543 1544 // Retrieve the aggregator for this name/tag combination or create one. 1545 rp := itr.m[id] 1546 if rp == nil { 1547 aggregator, emitter := itr.create() 1548 rp = &floatReduceIntegerPoint{ 1549 Name: curr.Name, 1550 Tags: tags, 1551 Aggregator: aggregator, 1552 Emitter: emitter, 1553 } 1554 itr.m[id] = rp 1555 } 1556 rp.Aggregator.AggregateFloat(curr) 1557 1558 // Attempt to emit points from the aggregator. 1559 points := rp.Emitter.Emit() 1560 if len(points) == 0 { 1561 continue 1562 } 1563 1564 for i := range points { 1565 points[i].Name = rp.Name 1566 points[i].Tags = rp.Tags 1567 } 1568 return points, nil 1569 } 1570 } 1571 1572 // floatReduceUnsignedIterator executes a reducer for every interval and buffers the result. 1573 type floatReduceUnsignedIterator struct { 1574 input *bufFloatIterator 1575 create func() (FloatPointAggregator, UnsignedPointEmitter) 1576 dims []string 1577 opt IteratorOptions 1578 points []UnsignedPoint 1579 keepTags bool 1580 } 1581 1582 func newFloatReduceUnsignedIterator(input FloatIterator, opt IteratorOptions, createFn func() (FloatPointAggregator, UnsignedPointEmitter)) *floatReduceUnsignedIterator { 1583 return &floatReduceUnsignedIterator{ 1584 input: newBufFloatIterator(input), 1585 create: createFn, 1586 dims: opt.GetDimensions(), 1587 opt: opt, 1588 } 1589 } 1590 1591 // Stats returns stats from the input iterator. 1592 func (itr *floatReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() } 1593 1594 // Close closes the iterator and all child iterators. 1595 func (itr *floatReduceUnsignedIterator) Close() error { return itr.input.Close() } 1596 1597 // Next returns the minimum value for the next available interval. 1598 func (itr *floatReduceUnsignedIterator) Next() (*UnsignedPoint, error) { 1599 // Calculate next window if we have no more points. 1600 if len(itr.points) == 0 { 1601 var err error 1602 itr.points, err = itr.reduce() 1603 if len(itr.points) == 0 { 1604 return nil, err 1605 } 1606 } 1607 1608 // Pop next point off the stack. 1609 p := &itr.points[len(itr.points)-1] 1610 itr.points = itr.points[:len(itr.points)-1] 1611 return p, nil 1612 } 1613 1614 // floatReduceUnsignedPoint stores the reduced data for a name/tag combination. 1615 type floatReduceUnsignedPoint struct { 1616 Name string 1617 Tags Tags 1618 Aggregator FloatPointAggregator 1619 Emitter UnsignedPointEmitter 1620 } 1621 1622 // reduce executes fn once for every point in the next window. 1623 // The previous value for the dimension is passed to fn. 1624 func (itr *floatReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) { 1625 // Calculate next window. 1626 var ( 1627 startTime, endTime int64 1628 window struct { 1629 name string 1630 tags string 1631 } 1632 ) 1633 for { 1634 p, err := itr.input.Next() 1635 if err != nil || p == nil { 1636 return nil, err 1637 } else if p.Nil { 1638 continue 1639 } 1640 1641 // Unread the point so it can be processed. 1642 itr.input.unread(p) 1643 startTime, endTime = itr.opt.Window(p.Time) 1644 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 1645 break 1646 } 1647 1648 // Create points by tags. 1649 m := make(map[string]*floatReduceUnsignedPoint) 1650 for { 1651 // Read next point. 1652 curr, err := itr.input.NextInWindow(startTime, endTime) 1653 if err != nil { 1654 return nil, err 1655 } else if curr == nil { 1656 break 1657 } else if curr.Nil { 1658 continue 1659 } else if curr.Name != window.name { 1660 itr.input.unread(curr) 1661 break 1662 } 1663 1664 // Ensure this point is within the same final window. 1665 if curr.Name != window.name { 1666 itr.input.unread(curr) 1667 break 1668 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 1669 itr.input.unread(curr) 1670 break 1671 } 1672 1673 // Retrieve the tags on this point for this level of the query. 1674 // This may be different than the bucket dimensions. 1675 tags := curr.Tags.Subset(itr.dims) 1676 id := tags.ID() 1677 1678 // Retrieve the aggregator for this name/tag combination or create one. 1679 rp := m[id] 1680 if rp == nil { 1681 aggregator, emitter := itr.create() 1682 rp = &floatReduceUnsignedPoint{ 1683 Name: curr.Name, 1684 Tags: tags, 1685 Aggregator: aggregator, 1686 Emitter: emitter, 1687 } 1688 m[id] = rp 1689 } 1690 rp.Aggregator.AggregateFloat(curr) 1691 } 1692 1693 keys := make([]string, 0, len(m)) 1694 for k := range m { 1695 keys = append(keys, k) 1696 } 1697 1698 // Reverse sort points by name & tag. 1699 // This ensures a consistent order of output. 1700 if len(keys) > 0 { 1701 var sorted sort.Interface = sort.StringSlice(keys) 1702 if itr.opt.Ascending { 1703 sorted = sort.Reverse(sorted) 1704 } 1705 sort.Sort(sorted) 1706 } 1707 1708 // Assume the points are already sorted until proven otherwise. 1709 sortedByTime := true 1710 // Emit the points for each name & tag combination. 1711 a := make([]UnsignedPoint, 0, len(m)) 1712 for _, k := range keys { 1713 rp := m[k] 1714 points := rp.Emitter.Emit() 1715 for i := len(points) - 1; i >= 0; i-- { 1716 points[i].Name = rp.Name 1717 if !itr.keepTags { 1718 points[i].Tags = rp.Tags 1719 } 1720 // Set the points time to the interval time if the reducer didn't provide one. 1721 if points[i].Time == ZeroTime { 1722 points[i].Time = startTime 1723 } else { 1724 sortedByTime = false 1725 } 1726 a = append(a, points[i]) 1727 } 1728 } 1729 // Points may be out of order. Perform a stable sort by time if requested. 1730 if !sortedByTime && itr.opt.Ordered { 1731 var sorted sort.Interface = unsignedPointsByTime(a) 1732 if itr.opt.Ascending { 1733 sorted = sort.Reverse(sorted) 1734 } 1735 sort.Stable(sorted) 1736 } 1737 return a, nil 1738 } 1739 1740 // floatStreamUnsignedIterator streams inputs into the iterator and emits points gradually. 1741 type floatStreamUnsignedIterator struct { 1742 input *bufFloatIterator 1743 create func() (FloatPointAggregator, UnsignedPointEmitter) 1744 dims []string 1745 opt IteratorOptions 1746 m map[string]*floatReduceUnsignedPoint 1747 points []UnsignedPoint 1748 } 1749 1750 // newFloatStreamUnsignedIterator returns a new instance of floatStreamUnsignedIterator. 1751 func newFloatStreamUnsignedIterator(input FloatIterator, createFn func() (FloatPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *floatStreamUnsignedIterator { 1752 return &floatStreamUnsignedIterator{ 1753 input: newBufFloatIterator(input), 1754 create: createFn, 1755 dims: opt.GetDimensions(), 1756 opt: opt, 1757 m: make(map[string]*floatReduceUnsignedPoint), 1758 } 1759 } 1760 1761 // Stats returns stats from the input iterator. 1762 func (itr *floatStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() } 1763 1764 // Close closes the iterator and all child iterators. 1765 func (itr *floatStreamUnsignedIterator) Close() error { return itr.input.Close() } 1766 1767 // Next returns the next value for the stream iterator. 1768 func (itr *floatStreamUnsignedIterator) Next() (*UnsignedPoint, error) { 1769 // Calculate next window if we have no more points. 1770 if len(itr.points) == 0 { 1771 var err error 1772 itr.points, err = itr.reduce() 1773 if len(itr.points) == 0 { 1774 return nil, err 1775 } 1776 } 1777 1778 // Pop next point off the stack. 1779 p := &itr.points[len(itr.points)-1] 1780 itr.points = itr.points[:len(itr.points)-1] 1781 return p, nil 1782 } 1783 1784 // reduce creates and manages aggregators for every point from the input. 1785 // After aggregating a point, it always tries to emit a value using the emitter. 1786 func (itr *floatStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) { 1787 // We have already read all of the input points. 1788 if itr.m == nil { 1789 return nil, nil 1790 } 1791 1792 for { 1793 // Read next point. 1794 curr, err := itr.input.Next() 1795 if err != nil { 1796 return nil, err 1797 } else if curr == nil { 1798 // Close all of the aggregators to flush any remaining points to emit. 1799 var points []UnsignedPoint 1800 for _, rp := range itr.m { 1801 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 1802 if err := aggregator.Close(); err != nil { 1803 return nil, err 1804 } 1805 1806 pts := rp.Emitter.Emit() 1807 if len(pts) == 0 { 1808 continue 1809 } 1810 1811 for i := range pts { 1812 pts[i].Name = rp.Name 1813 pts[i].Tags = rp.Tags 1814 } 1815 points = append(points, pts...) 1816 } 1817 } 1818 1819 // Eliminate the aggregators and emitters. 1820 itr.m = nil 1821 return points, nil 1822 } else if curr.Nil { 1823 continue 1824 } 1825 tags := curr.Tags.Subset(itr.dims) 1826 1827 id := curr.Name 1828 if len(tags.m) > 0 { 1829 id += "\x00" + tags.ID() 1830 } 1831 1832 // Retrieve the aggregator for this name/tag combination or create one. 1833 rp := itr.m[id] 1834 if rp == nil { 1835 aggregator, emitter := itr.create() 1836 rp = &floatReduceUnsignedPoint{ 1837 Name: curr.Name, 1838 Tags: tags, 1839 Aggregator: aggregator, 1840 Emitter: emitter, 1841 } 1842 itr.m[id] = rp 1843 } 1844 rp.Aggregator.AggregateFloat(curr) 1845 1846 // Attempt to emit points from the aggregator. 1847 points := rp.Emitter.Emit() 1848 if len(points) == 0 { 1849 continue 1850 } 1851 1852 for i := range points { 1853 points[i].Name = rp.Name 1854 points[i].Tags = rp.Tags 1855 } 1856 return points, nil 1857 } 1858 } 1859 1860 // floatReduceStringIterator executes a reducer for every interval and buffers the result. 1861 type floatReduceStringIterator struct { 1862 input *bufFloatIterator 1863 create func() (FloatPointAggregator, StringPointEmitter) 1864 dims []string 1865 opt IteratorOptions 1866 points []StringPoint 1867 keepTags bool 1868 } 1869 1870 func newFloatReduceStringIterator(input FloatIterator, opt IteratorOptions, createFn func() (FloatPointAggregator, StringPointEmitter)) *floatReduceStringIterator { 1871 return &floatReduceStringIterator{ 1872 input: newBufFloatIterator(input), 1873 create: createFn, 1874 dims: opt.GetDimensions(), 1875 opt: opt, 1876 } 1877 } 1878 1879 // Stats returns stats from the input iterator. 1880 func (itr *floatReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() } 1881 1882 // Close closes the iterator and all child iterators. 1883 func (itr *floatReduceStringIterator) Close() error { return itr.input.Close() } 1884 1885 // Next returns the minimum value for the next available interval. 1886 func (itr *floatReduceStringIterator) Next() (*StringPoint, error) { 1887 // Calculate next window if we have no more points. 1888 if len(itr.points) == 0 { 1889 var err error 1890 itr.points, err = itr.reduce() 1891 if len(itr.points) == 0 { 1892 return nil, err 1893 } 1894 } 1895 1896 // Pop next point off the stack. 1897 p := &itr.points[len(itr.points)-1] 1898 itr.points = itr.points[:len(itr.points)-1] 1899 return p, nil 1900 } 1901 1902 // floatReduceStringPoint stores the reduced data for a name/tag combination. 1903 type floatReduceStringPoint struct { 1904 Name string 1905 Tags Tags 1906 Aggregator FloatPointAggregator 1907 Emitter StringPointEmitter 1908 } 1909 1910 // reduce executes fn once for every point in the next window. 1911 // The previous value for the dimension is passed to fn. 1912 func (itr *floatReduceStringIterator) reduce() ([]StringPoint, error) { 1913 // Calculate next window. 1914 var ( 1915 startTime, endTime int64 1916 window struct { 1917 name string 1918 tags string 1919 } 1920 ) 1921 for { 1922 p, err := itr.input.Next() 1923 if err != nil || p == nil { 1924 return nil, err 1925 } else if p.Nil { 1926 continue 1927 } 1928 1929 // Unread the point so it can be processed. 1930 itr.input.unread(p) 1931 startTime, endTime = itr.opt.Window(p.Time) 1932 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 1933 break 1934 } 1935 1936 // Create points by tags. 1937 m := make(map[string]*floatReduceStringPoint) 1938 for { 1939 // Read next point. 1940 curr, err := itr.input.NextInWindow(startTime, endTime) 1941 if err != nil { 1942 return nil, err 1943 } else if curr == nil { 1944 break 1945 } else if curr.Nil { 1946 continue 1947 } else if curr.Name != window.name { 1948 itr.input.unread(curr) 1949 break 1950 } 1951 1952 // Ensure this point is within the same final window. 1953 if curr.Name != window.name { 1954 itr.input.unread(curr) 1955 break 1956 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 1957 itr.input.unread(curr) 1958 break 1959 } 1960 1961 // Retrieve the tags on this point for this level of the query. 1962 // This may be different than the bucket dimensions. 1963 tags := curr.Tags.Subset(itr.dims) 1964 id := tags.ID() 1965 1966 // Retrieve the aggregator for this name/tag combination or create one. 1967 rp := m[id] 1968 if rp == nil { 1969 aggregator, emitter := itr.create() 1970 rp = &floatReduceStringPoint{ 1971 Name: curr.Name, 1972 Tags: tags, 1973 Aggregator: aggregator, 1974 Emitter: emitter, 1975 } 1976 m[id] = rp 1977 } 1978 rp.Aggregator.AggregateFloat(curr) 1979 } 1980 1981 keys := make([]string, 0, len(m)) 1982 for k := range m { 1983 keys = append(keys, k) 1984 } 1985 1986 // Reverse sort points by name & tag. 1987 // This ensures a consistent order of output. 1988 if len(keys) > 0 { 1989 var sorted sort.Interface = sort.StringSlice(keys) 1990 if itr.opt.Ascending { 1991 sorted = sort.Reverse(sorted) 1992 } 1993 sort.Sort(sorted) 1994 } 1995 1996 // Assume the points are already sorted until proven otherwise. 1997 sortedByTime := true 1998 // Emit the points for each name & tag combination. 1999 a := make([]StringPoint, 0, len(m)) 2000 for _, k := range keys { 2001 rp := m[k] 2002 points := rp.Emitter.Emit() 2003 for i := len(points) - 1; i >= 0; i-- { 2004 points[i].Name = rp.Name 2005 if !itr.keepTags { 2006 points[i].Tags = rp.Tags 2007 } 2008 // Set the points time to the interval time if the reducer didn't provide one. 2009 if points[i].Time == ZeroTime { 2010 points[i].Time = startTime 2011 } else { 2012 sortedByTime = false 2013 } 2014 a = append(a, points[i]) 2015 } 2016 } 2017 // Points may be out of order. Perform a stable sort by time if requested. 2018 if !sortedByTime && itr.opt.Ordered { 2019 var sorted sort.Interface = stringPointsByTime(a) 2020 if itr.opt.Ascending { 2021 sorted = sort.Reverse(sorted) 2022 } 2023 sort.Stable(sorted) 2024 } 2025 return a, nil 2026 } 2027 2028 // floatStreamStringIterator streams inputs into the iterator and emits points gradually. 2029 type floatStreamStringIterator struct { 2030 input *bufFloatIterator 2031 create func() (FloatPointAggregator, StringPointEmitter) 2032 dims []string 2033 opt IteratorOptions 2034 m map[string]*floatReduceStringPoint 2035 points []StringPoint 2036 } 2037 2038 // newFloatStreamStringIterator returns a new instance of floatStreamStringIterator. 2039 func newFloatStreamStringIterator(input FloatIterator, createFn func() (FloatPointAggregator, StringPointEmitter), opt IteratorOptions) *floatStreamStringIterator { 2040 return &floatStreamStringIterator{ 2041 input: newBufFloatIterator(input), 2042 create: createFn, 2043 dims: opt.GetDimensions(), 2044 opt: opt, 2045 m: make(map[string]*floatReduceStringPoint), 2046 } 2047 } 2048 2049 // Stats returns stats from the input iterator. 2050 func (itr *floatStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() } 2051 2052 // Close closes the iterator and all child iterators. 2053 func (itr *floatStreamStringIterator) Close() error { return itr.input.Close() } 2054 2055 // Next returns the next value for the stream iterator. 2056 func (itr *floatStreamStringIterator) Next() (*StringPoint, error) { 2057 // Calculate next window if we have no more points. 2058 if len(itr.points) == 0 { 2059 var err error 2060 itr.points, err = itr.reduce() 2061 if len(itr.points) == 0 { 2062 return nil, err 2063 } 2064 } 2065 2066 // Pop next point off the stack. 2067 p := &itr.points[len(itr.points)-1] 2068 itr.points = itr.points[:len(itr.points)-1] 2069 return p, nil 2070 } 2071 2072 // reduce creates and manages aggregators for every point from the input. 2073 // After aggregating a point, it always tries to emit a value using the emitter. 2074 func (itr *floatStreamStringIterator) reduce() ([]StringPoint, error) { 2075 // We have already read all of the input points. 2076 if itr.m == nil { 2077 return nil, nil 2078 } 2079 2080 for { 2081 // Read next point. 2082 curr, err := itr.input.Next() 2083 if err != nil { 2084 return nil, err 2085 } else if curr == nil { 2086 // Close all of the aggregators to flush any remaining points to emit. 2087 var points []StringPoint 2088 for _, rp := range itr.m { 2089 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 2090 if err := aggregator.Close(); err != nil { 2091 return nil, err 2092 } 2093 2094 pts := rp.Emitter.Emit() 2095 if len(pts) == 0 { 2096 continue 2097 } 2098 2099 for i := range pts { 2100 pts[i].Name = rp.Name 2101 pts[i].Tags = rp.Tags 2102 } 2103 points = append(points, pts...) 2104 } 2105 } 2106 2107 // Eliminate the aggregators and emitters. 2108 itr.m = nil 2109 return points, nil 2110 } else if curr.Nil { 2111 continue 2112 } 2113 tags := curr.Tags.Subset(itr.dims) 2114 2115 id := curr.Name 2116 if len(tags.m) > 0 { 2117 id += "\x00" + tags.ID() 2118 } 2119 2120 // Retrieve the aggregator for this name/tag combination or create one. 2121 rp := itr.m[id] 2122 if rp == nil { 2123 aggregator, emitter := itr.create() 2124 rp = &floatReduceStringPoint{ 2125 Name: curr.Name, 2126 Tags: tags, 2127 Aggregator: aggregator, 2128 Emitter: emitter, 2129 } 2130 itr.m[id] = rp 2131 } 2132 rp.Aggregator.AggregateFloat(curr) 2133 2134 // Attempt to emit points from the aggregator. 2135 points := rp.Emitter.Emit() 2136 if len(points) == 0 { 2137 continue 2138 } 2139 2140 for i := range points { 2141 points[i].Name = rp.Name 2142 points[i].Tags = rp.Tags 2143 } 2144 return points, nil 2145 } 2146 } 2147 2148 // floatReduceBooleanIterator executes a reducer for every interval and buffers the result. 2149 type floatReduceBooleanIterator struct { 2150 input *bufFloatIterator 2151 create func() (FloatPointAggregator, BooleanPointEmitter) 2152 dims []string 2153 opt IteratorOptions 2154 points []BooleanPoint 2155 keepTags bool 2156 } 2157 2158 func newFloatReduceBooleanIterator(input FloatIterator, opt IteratorOptions, createFn func() (FloatPointAggregator, BooleanPointEmitter)) *floatReduceBooleanIterator { 2159 return &floatReduceBooleanIterator{ 2160 input: newBufFloatIterator(input), 2161 create: createFn, 2162 dims: opt.GetDimensions(), 2163 opt: opt, 2164 } 2165 } 2166 2167 // Stats returns stats from the input iterator. 2168 func (itr *floatReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() } 2169 2170 // Close closes the iterator and all child iterators. 2171 func (itr *floatReduceBooleanIterator) Close() error { return itr.input.Close() } 2172 2173 // Next returns the minimum value for the next available interval. 2174 func (itr *floatReduceBooleanIterator) Next() (*BooleanPoint, error) { 2175 // Calculate next window if we have no more points. 2176 if len(itr.points) == 0 { 2177 var err error 2178 itr.points, err = itr.reduce() 2179 if len(itr.points) == 0 { 2180 return nil, err 2181 } 2182 } 2183 2184 // Pop next point off the stack. 2185 p := &itr.points[len(itr.points)-1] 2186 itr.points = itr.points[:len(itr.points)-1] 2187 return p, nil 2188 } 2189 2190 // floatReduceBooleanPoint stores the reduced data for a name/tag combination. 2191 type floatReduceBooleanPoint struct { 2192 Name string 2193 Tags Tags 2194 Aggregator FloatPointAggregator 2195 Emitter BooleanPointEmitter 2196 } 2197 2198 // reduce executes fn once for every point in the next window. 2199 // The previous value for the dimension is passed to fn. 2200 func (itr *floatReduceBooleanIterator) reduce() ([]BooleanPoint, error) { 2201 // Calculate next window. 2202 var ( 2203 startTime, endTime int64 2204 window struct { 2205 name string 2206 tags string 2207 } 2208 ) 2209 for { 2210 p, err := itr.input.Next() 2211 if err != nil || p == nil { 2212 return nil, err 2213 } else if p.Nil { 2214 continue 2215 } 2216 2217 // Unread the point so it can be processed. 2218 itr.input.unread(p) 2219 startTime, endTime = itr.opt.Window(p.Time) 2220 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 2221 break 2222 } 2223 2224 // Create points by tags. 2225 m := make(map[string]*floatReduceBooleanPoint) 2226 for { 2227 // Read next point. 2228 curr, err := itr.input.NextInWindow(startTime, endTime) 2229 if err != nil { 2230 return nil, err 2231 } else if curr == nil { 2232 break 2233 } else if curr.Nil { 2234 continue 2235 } else if curr.Name != window.name { 2236 itr.input.unread(curr) 2237 break 2238 } 2239 2240 // Ensure this point is within the same final window. 2241 if curr.Name != window.name { 2242 itr.input.unread(curr) 2243 break 2244 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 2245 itr.input.unread(curr) 2246 break 2247 } 2248 2249 // Retrieve the tags on this point for this level of the query. 2250 // This may be different than the bucket dimensions. 2251 tags := curr.Tags.Subset(itr.dims) 2252 id := tags.ID() 2253 2254 // Retrieve the aggregator for this name/tag combination or create one. 2255 rp := m[id] 2256 if rp == nil { 2257 aggregator, emitter := itr.create() 2258 rp = &floatReduceBooleanPoint{ 2259 Name: curr.Name, 2260 Tags: tags, 2261 Aggregator: aggregator, 2262 Emitter: emitter, 2263 } 2264 m[id] = rp 2265 } 2266 rp.Aggregator.AggregateFloat(curr) 2267 } 2268 2269 keys := make([]string, 0, len(m)) 2270 for k := range m { 2271 keys = append(keys, k) 2272 } 2273 2274 // Reverse sort points by name & tag. 2275 // This ensures a consistent order of output. 2276 if len(keys) > 0 { 2277 var sorted sort.Interface = sort.StringSlice(keys) 2278 if itr.opt.Ascending { 2279 sorted = sort.Reverse(sorted) 2280 } 2281 sort.Sort(sorted) 2282 } 2283 2284 // Assume the points are already sorted until proven otherwise. 2285 sortedByTime := true 2286 // Emit the points for each name & tag combination. 2287 a := make([]BooleanPoint, 0, len(m)) 2288 for _, k := range keys { 2289 rp := m[k] 2290 points := rp.Emitter.Emit() 2291 for i := len(points) - 1; i >= 0; i-- { 2292 points[i].Name = rp.Name 2293 if !itr.keepTags { 2294 points[i].Tags = rp.Tags 2295 } 2296 // Set the points time to the interval time if the reducer didn't provide one. 2297 if points[i].Time == ZeroTime { 2298 points[i].Time = startTime 2299 } else { 2300 sortedByTime = false 2301 } 2302 a = append(a, points[i]) 2303 } 2304 } 2305 // Points may be out of order. Perform a stable sort by time if requested. 2306 if !sortedByTime && itr.opt.Ordered { 2307 var sorted sort.Interface = booleanPointsByTime(a) 2308 if itr.opt.Ascending { 2309 sorted = sort.Reverse(sorted) 2310 } 2311 sort.Stable(sorted) 2312 } 2313 return a, nil 2314 } 2315 2316 // floatStreamBooleanIterator streams inputs into the iterator and emits points gradually. 2317 type floatStreamBooleanIterator struct { 2318 input *bufFloatIterator 2319 create func() (FloatPointAggregator, BooleanPointEmitter) 2320 dims []string 2321 opt IteratorOptions 2322 m map[string]*floatReduceBooleanPoint 2323 points []BooleanPoint 2324 } 2325 2326 // newFloatStreamBooleanIterator returns a new instance of floatStreamBooleanIterator. 2327 func newFloatStreamBooleanIterator(input FloatIterator, createFn func() (FloatPointAggregator, BooleanPointEmitter), opt IteratorOptions) *floatStreamBooleanIterator { 2328 return &floatStreamBooleanIterator{ 2329 input: newBufFloatIterator(input), 2330 create: createFn, 2331 dims: opt.GetDimensions(), 2332 opt: opt, 2333 m: make(map[string]*floatReduceBooleanPoint), 2334 } 2335 } 2336 2337 // Stats returns stats from the input iterator. 2338 func (itr *floatStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() } 2339 2340 // Close closes the iterator and all child iterators. 2341 func (itr *floatStreamBooleanIterator) Close() error { return itr.input.Close() } 2342 2343 // Next returns the next value for the stream iterator. 2344 func (itr *floatStreamBooleanIterator) Next() (*BooleanPoint, error) { 2345 // Calculate next window if we have no more points. 2346 if len(itr.points) == 0 { 2347 var err error 2348 itr.points, err = itr.reduce() 2349 if len(itr.points) == 0 { 2350 return nil, err 2351 } 2352 } 2353 2354 // Pop next point off the stack. 2355 p := &itr.points[len(itr.points)-1] 2356 itr.points = itr.points[:len(itr.points)-1] 2357 return p, nil 2358 } 2359 2360 // reduce creates and manages aggregators for every point from the input. 2361 // After aggregating a point, it always tries to emit a value using the emitter. 2362 func (itr *floatStreamBooleanIterator) reduce() ([]BooleanPoint, error) { 2363 // We have already read all of the input points. 2364 if itr.m == nil { 2365 return nil, nil 2366 } 2367 2368 for { 2369 // Read next point. 2370 curr, err := itr.input.Next() 2371 if err != nil { 2372 return nil, err 2373 } else if curr == nil { 2374 // Close all of the aggregators to flush any remaining points to emit. 2375 var points []BooleanPoint 2376 for _, rp := range itr.m { 2377 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 2378 if err := aggregator.Close(); err != nil { 2379 return nil, err 2380 } 2381 2382 pts := rp.Emitter.Emit() 2383 if len(pts) == 0 { 2384 continue 2385 } 2386 2387 for i := range pts { 2388 pts[i].Name = rp.Name 2389 pts[i].Tags = rp.Tags 2390 } 2391 points = append(points, pts...) 2392 } 2393 } 2394 2395 // Eliminate the aggregators and emitters. 2396 itr.m = nil 2397 return points, nil 2398 } else if curr.Nil { 2399 continue 2400 } 2401 tags := curr.Tags.Subset(itr.dims) 2402 2403 id := curr.Name 2404 if len(tags.m) > 0 { 2405 id += "\x00" + tags.ID() 2406 } 2407 2408 // Retrieve the aggregator for this name/tag combination or create one. 2409 rp := itr.m[id] 2410 if rp == nil { 2411 aggregator, emitter := itr.create() 2412 rp = &floatReduceBooleanPoint{ 2413 Name: curr.Name, 2414 Tags: tags, 2415 Aggregator: aggregator, 2416 Emitter: emitter, 2417 } 2418 itr.m[id] = rp 2419 } 2420 rp.Aggregator.AggregateFloat(curr) 2421 2422 // Attempt to emit points from the aggregator. 2423 points := rp.Emitter.Emit() 2424 if len(points) == 0 { 2425 continue 2426 } 2427 2428 for i := range points { 2429 points[i].Name = rp.Name 2430 points[i].Tags = rp.Tags 2431 } 2432 return points, nil 2433 } 2434 } 2435 2436 // floatDedupeIterator only outputs unique points. 2437 // This differs from the DistinctIterator in that it compares all aux fields too. 2438 // This iterator is relatively inefficient and should only be used on small 2439 // datasets such as meta query results. 2440 type floatDedupeIterator struct { 2441 input FloatIterator 2442 m map[string]struct{} // lookup of points already sent 2443 } 2444 2445 type floatIteratorMapper struct { 2446 cur Cursor 2447 row Row 2448 driver IteratorMap // which iterator to use for the primary value, can be nil 2449 fields []IteratorMap // which iterator to use for an aux field 2450 point FloatPoint 2451 } 2452 2453 func newFloatIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *floatIteratorMapper { 2454 return &floatIteratorMapper{ 2455 cur: cur, 2456 driver: driver, 2457 fields: fields, 2458 point: FloatPoint{ 2459 Aux: make([]interface{}, len(fields)), 2460 }, 2461 } 2462 } 2463 2464 func (itr *floatIteratorMapper) Next() (*FloatPoint, error) { 2465 if !itr.cur.Scan(&itr.row) { 2466 if err := itr.cur.Err(); err != nil { 2467 return nil, err 2468 } 2469 return nil, nil 2470 } 2471 2472 itr.point.Time = itr.row.Time 2473 itr.point.Name = itr.row.Series.Name 2474 itr.point.Tags = itr.row.Series.Tags 2475 2476 if itr.driver != nil { 2477 if v := itr.driver.Value(&itr.row); v != nil { 2478 if v, ok := castToFloat(v); ok { 2479 itr.point.Value = v 2480 itr.point.Nil = false 2481 } else { 2482 itr.point.Value = 0 2483 itr.point.Nil = true 2484 } 2485 } else { 2486 itr.point.Value = 0 2487 itr.point.Nil = true 2488 } 2489 } 2490 for i, f := range itr.fields { 2491 itr.point.Aux[i] = f.Value(&itr.row) 2492 } 2493 return &itr.point, nil 2494 } 2495 2496 func (itr *floatIteratorMapper) Stats() IteratorStats { 2497 return itr.cur.Stats() 2498 } 2499 2500 func (itr *floatIteratorMapper) Close() error { 2501 return itr.cur.Close() 2502 } 2503 2504 type floatFilterIterator struct { 2505 input FloatIterator 2506 cond influxql.Expr 2507 opt IteratorOptions 2508 m map[string]interface{} 2509 } 2510 2511 func newFloatFilterIterator(input FloatIterator, cond influxql.Expr, opt IteratorOptions) FloatIterator { 2512 // Strip out time conditions from the WHERE clause. 2513 // TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct. 2514 n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node { 2515 switch n := n.(type) { 2516 case *influxql.BinaryExpr: 2517 if n.LHS.String() == "time" { 2518 return &influxql.BooleanLiteral{Val: true} 2519 } 2520 } 2521 return n 2522 }) 2523 2524 cond, _ = n.(influxql.Expr) 2525 if cond == nil { 2526 return input 2527 } else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val { 2528 return input 2529 } 2530 2531 return &floatFilterIterator{ 2532 input: input, 2533 cond: cond, 2534 opt: opt, 2535 m: make(map[string]interface{}), 2536 } 2537 } 2538 2539 func (itr *floatFilterIterator) Stats() IteratorStats { return itr.input.Stats() } 2540 func (itr *floatFilterIterator) Close() error { return itr.input.Close() } 2541 2542 func (itr *floatFilterIterator) Next() (*FloatPoint, error) { 2543 for { 2544 p, err := itr.input.Next() 2545 if err != nil || p == nil { 2546 return nil, err 2547 } 2548 2549 for i, ref := range itr.opt.Aux { 2550 itr.m[ref.Val] = p.Aux[i] 2551 } 2552 for k, v := range p.Tags.KeyValues() { 2553 itr.m[k] = v 2554 } 2555 2556 if !influxql.EvalBool(itr.cond, itr.m) { 2557 continue 2558 } 2559 return p, nil 2560 } 2561 } 2562 2563 type floatTagSubsetIterator struct { 2564 input FloatIterator 2565 point FloatPoint 2566 lastTags Tags 2567 dimensions []string 2568 } 2569 2570 func newFloatTagSubsetIterator(input FloatIterator, opt IteratorOptions) *floatTagSubsetIterator { 2571 return &floatTagSubsetIterator{ 2572 input: input, 2573 dimensions: opt.GetDimensions(), 2574 } 2575 } 2576 2577 func (itr *floatTagSubsetIterator) Next() (*FloatPoint, error) { 2578 p, err := itr.input.Next() 2579 if err != nil { 2580 return nil, err 2581 } else if p == nil { 2582 return nil, nil 2583 } 2584 2585 itr.point.Name = p.Name 2586 if !p.Tags.Equal(itr.lastTags) { 2587 itr.point.Tags = p.Tags.Subset(itr.dimensions) 2588 itr.lastTags = p.Tags 2589 } 2590 itr.point.Time = p.Time 2591 itr.point.Value = p.Value 2592 itr.point.Aux = p.Aux 2593 itr.point.Aggregated = p.Aggregated 2594 itr.point.Nil = p.Nil 2595 return &itr.point, nil 2596 } 2597 2598 func (itr *floatTagSubsetIterator) Stats() IteratorStats { 2599 return itr.input.Stats() 2600 } 2601 2602 func (itr *floatTagSubsetIterator) Close() error { 2603 return itr.input.Close() 2604 } 2605 2606 // newFloatDedupeIterator returns a new instance of floatDedupeIterator. 2607 func newFloatDedupeIterator(input FloatIterator) *floatDedupeIterator { 2608 return &floatDedupeIterator{ 2609 input: input, 2610 m: make(map[string]struct{}), 2611 } 2612 } 2613 2614 // Stats returns stats from the input iterator. 2615 func (itr *floatDedupeIterator) Stats() IteratorStats { return itr.input.Stats() } 2616 2617 // Close closes the iterator and all child iterators. 2618 func (itr *floatDedupeIterator) Close() error { return itr.input.Close() } 2619 2620 // Next returns the next unique point from the input iterator. 2621 func (itr *floatDedupeIterator) Next() (*FloatPoint, error) { 2622 for { 2623 // Read next point. 2624 p, err := itr.input.Next() 2625 if p == nil || err != nil { 2626 return nil, err 2627 } 2628 2629 // Serialize to bytes to store in lookup. 2630 buf, err := proto.Marshal(encodeFloatPoint(p)) 2631 if err != nil { 2632 return nil, err 2633 } 2634 2635 // If the point has already been output then move to the next point. 2636 if _, ok := itr.m[string(buf)]; ok { 2637 continue 2638 } 2639 2640 // Otherwise mark it as emitted and return point. 2641 itr.m[string(buf)] = struct{}{} 2642 return p, nil 2643 } 2644 } 2645 2646 // floatReaderIterator represents an iterator that streams from a reader. 2647 type floatReaderIterator struct { 2648 r io.Reader 2649 dec *FloatPointDecoder 2650 } 2651 2652 // newFloatReaderIterator returns a new instance of floatReaderIterator. 2653 func newFloatReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *floatReaderIterator { 2654 dec := NewFloatPointDecoder(ctx, r) 2655 dec.stats = stats 2656 2657 return &floatReaderIterator{ 2658 r: r, 2659 dec: dec, 2660 } 2661 } 2662 2663 // Stats returns stats about points processed. 2664 func (itr *floatReaderIterator) Stats() IteratorStats { return itr.dec.stats } 2665 2666 // Close closes the underlying reader, if applicable. 2667 func (itr *floatReaderIterator) Close() error { 2668 if r, ok := itr.r.(io.ReadCloser); ok { 2669 return r.Close() 2670 } 2671 return nil 2672 } 2673 2674 // Next returns the next point from the iterator. 2675 func (itr *floatReaderIterator) Next() (*FloatPoint, error) { 2676 // OPTIMIZE(benbjohnson): Reuse point on iterator. 2677 2678 // Unmarshal next point. 2679 p := &FloatPoint{} 2680 if err := itr.dec.DecodeFloatPoint(p); err == io.EOF { 2681 return nil, nil 2682 } else if err != nil { 2683 return nil, err 2684 } 2685 return p, nil 2686 } 2687 2688 // IntegerIterator represents a stream of integer points. 2689 type IntegerIterator interface { 2690 Iterator 2691 Next() (*IntegerPoint, error) 2692 } 2693 2694 // newIntegerIterators converts a slice of Iterator to a slice of IntegerIterator. 2695 // Drop and closes any iterator in itrs that is not a IntegerIterator and cannot 2696 // be cast to a IntegerIterator. 2697 func newIntegerIterators(itrs []Iterator) []IntegerIterator { 2698 a := make([]IntegerIterator, 0, len(itrs)) 2699 for _, itr := range itrs { 2700 switch itr := itr.(type) { 2701 case IntegerIterator: 2702 a = append(a, itr) 2703 default: 2704 itr.Close() 2705 } 2706 } 2707 return a 2708 } 2709 2710 // bufIntegerIterator represents a buffered IntegerIterator. 2711 type bufIntegerIterator struct { 2712 itr IntegerIterator 2713 buf *IntegerPoint 2714 } 2715 2716 // newBufIntegerIterator returns a buffered IntegerIterator. 2717 func newBufIntegerIterator(itr IntegerIterator) *bufIntegerIterator { 2718 return &bufIntegerIterator{itr: itr} 2719 } 2720 2721 // Stats returns statistics from the input iterator. 2722 func (itr *bufIntegerIterator) Stats() IteratorStats { return itr.itr.Stats() } 2723 2724 // Close closes the underlying iterator. 2725 func (itr *bufIntegerIterator) Close() error { return itr.itr.Close() } 2726 2727 // peek returns the next point without removing it from the iterator. 2728 func (itr *bufIntegerIterator) peek() (*IntegerPoint, error) { 2729 p, err := itr.Next() 2730 if err != nil { 2731 return nil, err 2732 } 2733 itr.unread(p) 2734 return p, nil 2735 } 2736 2737 // peekTime returns the time of the next point. 2738 // Returns zero time if no more points available. 2739 func (itr *bufIntegerIterator) peekTime() (int64, error) { 2740 p, err := itr.peek() 2741 if p == nil || err != nil { 2742 return ZeroTime, err 2743 } 2744 return p.Time, nil 2745 } 2746 2747 // Next returns the current buffer, if exists, or calls the underlying iterator. 2748 func (itr *bufIntegerIterator) Next() (*IntegerPoint, error) { 2749 buf := itr.buf 2750 if buf != nil { 2751 itr.buf = nil 2752 return buf, nil 2753 } 2754 return itr.itr.Next() 2755 } 2756 2757 // NextInWindow returns the next value if it is between [startTime, endTime). 2758 // If the next value is outside the range then it is moved to the buffer. 2759 func (itr *bufIntegerIterator) NextInWindow(startTime, endTime int64) (*IntegerPoint, error) { 2760 v, err := itr.Next() 2761 if v == nil || err != nil { 2762 return nil, err 2763 } else if t := v.Time; t >= endTime || t < startTime { 2764 itr.unread(v) 2765 return nil, nil 2766 } 2767 return v, nil 2768 } 2769 2770 // unread sets v to the buffer. It is read on the next call to Next(). 2771 func (itr *bufIntegerIterator) unread(v *IntegerPoint) { itr.buf = v } 2772 2773 // integerMergeIterator represents an iterator that combines multiple integer iterators. 2774 type integerMergeIterator struct { 2775 inputs []IntegerIterator 2776 heap *integerMergeHeap 2777 init bool 2778 2779 closed bool 2780 mu sync.RWMutex 2781 2782 // Current iterator and window. 2783 curr *integerMergeHeapItem 2784 window struct { 2785 name string 2786 tags string 2787 startTime int64 2788 endTime int64 2789 } 2790 } 2791 2792 // newIntegerMergeIterator returns a new instance of integerMergeIterator. 2793 func newIntegerMergeIterator(inputs []IntegerIterator, opt IteratorOptions) *integerMergeIterator { 2794 itr := &integerMergeIterator{ 2795 inputs: inputs, 2796 heap: &integerMergeHeap{ 2797 items: make([]*integerMergeHeapItem, 0, len(inputs)), 2798 opt: opt, 2799 }, 2800 } 2801 2802 // Initialize heap items. 2803 for _, input := range inputs { 2804 // Wrap in buffer, ignore any inputs without anymore points. 2805 bufInput := newBufIntegerIterator(input) 2806 2807 // Append to the heap. 2808 itr.heap.items = append(itr.heap.items, &integerMergeHeapItem{itr: bufInput}) 2809 } 2810 2811 return itr 2812 } 2813 2814 // Stats returns an aggregation of stats from the underlying iterators. 2815 func (itr *integerMergeIterator) Stats() IteratorStats { 2816 var stats IteratorStats 2817 for _, input := range itr.inputs { 2818 stats.Add(input.Stats()) 2819 } 2820 return stats 2821 } 2822 2823 // Close closes the underlying iterators. 2824 func (itr *integerMergeIterator) Close() error { 2825 itr.mu.Lock() 2826 defer itr.mu.Unlock() 2827 2828 for _, input := range itr.inputs { 2829 input.Close() 2830 } 2831 itr.curr = nil 2832 itr.inputs = nil 2833 itr.heap.items = nil 2834 itr.closed = true 2835 return nil 2836 } 2837 2838 // Next returns the next point from the iterator. 2839 func (itr *integerMergeIterator) Next() (*IntegerPoint, error) { 2840 itr.mu.RLock() 2841 defer itr.mu.RUnlock() 2842 if itr.closed { 2843 return nil, nil 2844 } 2845 2846 // Initialize the heap. This needs to be done lazily on the first call to this iterator 2847 // so that iterator initialization done through the Select() call returns quickly. 2848 // Queries can only be interrupted after the Select() call completes so any operations 2849 // done during iterator creation cannot be interrupted, which is why we do it here 2850 // instead so an interrupt can happen while initializing the heap. 2851 if !itr.init { 2852 items := itr.heap.items 2853 itr.heap.items = make([]*integerMergeHeapItem, 0, len(items)) 2854 for _, item := range items { 2855 if p, err := item.itr.peek(); err != nil { 2856 return nil, err 2857 } else if p == nil { 2858 continue 2859 } 2860 itr.heap.items = append(itr.heap.items, item) 2861 } 2862 heap.Init(itr.heap) 2863 itr.init = true 2864 } 2865 2866 for { 2867 // Retrieve the next iterator if we don't have one. 2868 if itr.curr == nil { 2869 if len(itr.heap.items) == 0 { 2870 return nil, nil 2871 } 2872 itr.curr = heap.Pop(itr.heap).(*integerMergeHeapItem) 2873 2874 // Read point and set current window. 2875 p, err := itr.curr.itr.Next() 2876 if err != nil { 2877 return nil, err 2878 } 2879 tags := p.Tags.Subset(itr.heap.opt.Dimensions) 2880 itr.window.name, itr.window.tags = p.Name, tags.ID() 2881 itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time) 2882 return p, nil 2883 } 2884 2885 // Read the next point from the current iterator. 2886 p, err := itr.curr.itr.Next() 2887 if err != nil { 2888 return nil, err 2889 } 2890 2891 // If there are no more points then remove iterator from heap and find next. 2892 if p == nil { 2893 itr.curr = nil 2894 continue 2895 } 2896 2897 // Check if the point is inside of our current window. 2898 inWindow := true 2899 if window := itr.window; window.name != p.Name { 2900 inWindow = false 2901 } else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() { 2902 inWindow = false 2903 } else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime { 2904 inWindow = false 2905 } else if !opt.Ascending && p.Time < window.startTime { 2906 inWindow = false 2907 } 2908 2909 // If it's outside our window then push iterator back on the heap and find new iterator. 2910 if !inWindow { 2911 itr.curr.itr.unread(p) 2912 heap.Push(itr.heap, itr.curr) 2913 itr.curr = nil 2914 continue 2915 } 2916 2917 return p, nil 2918 } 2919 } 2920 2921 // integerMergeHeap represents a heap of integerMergeHeapItems. 2922 // Items are sorted by their next window and then by name/tags. 2923 type integerMergeHeap struct { 2924 opt IteratorOptions 2925 items []*integerMergeHeapItem 2926 } 2927 2928 func (h *integerMergeHeap) Len() int { return len(h.items) } 2929 func (h *integerMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] } 2930 func (h *integerMergeHeap) Less(i, j int) bool { 2931 x, err := h.items[i].itr.peek() 2932 if err != nil { 2933 return true 2934 } 2935 y, err := h.items[j].itr.peek() 2936 if err != nil { 2937 return false 2938 } 2939 2940 if h.opt.Ascending { 2941 if x.Name != y.Name { 2942 return x.Name < y.Name 2943 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() { 2944 return xTags.ID() < yTags.ID() 2945 } 2946 } else { 2947 if x.Name != y.Name { 2948 return x.Name > y.Name 2949 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() { 2950 return xTags.ID() > yTags.ID() 2951 } 2952 } 2953 2954 xt, _ := h.opt.Window(x.Time) 2955 yt, _ := h.opt.Window(y.Time) 2956 2957 if h.opt.Ascending { 2958 return xt < yt 2959 } 2960 return xt > yt 2961 } 2962 2963 func (h *integerMergeHeap) Push(x interface{}) { 2964 h.items = append(h.items, x.(*integerMergeHeapItem)) 2965 } 2966 2967 func (h *integerMergeHeap) Pop() interface{} { 2968 old := h.items 2969 n := len(old) 2970 item := old[n-1] 2971 h.items = old[0 : n-1] 2972 return item 2973 } 2974 2975 type integerMergeHeapItem struct { 2976 itr *bufIntegerIterator 2977 } 2978 2979 // integerSortedMergeIterator is an iterator that sorts and merges multiple iterators into one. 2980 type integerSortedMergeIterator struct { 2981 inputs []IntegerIterator 2982 heap *integerSortedMergeHeap 2983 init bool 2984 } 2985 2986 // newIntegerSortedMergeIterator returns an instance of integerSortedMergeIterator. 2987 func newIntegerSortedMergeIterator(inputs []IntegerIterator, opt IteratorOptions) Iterator { 2988 itr := &integerSortedMergeIterator{ 2989 inputs: inputs, 2990 heap: &integerSortedMergeHeap{ 2991 items: make([]*integerSortedMergeHeapItem, 0, len(inputs)), 2992 opt: opt, 2993 }, 2994 } 2995 2996 // Initialize heap items. 2997 for _, input := range inputs { 2998 // Append to the heap. 2999 itr.heap.items = append(itr.heap.items, &integerSortedMergeHeapItem{itr: input}) 3000 } 3001 3002 return itr 3003 } 3004 3005 // Stats returns an aggregation of stats from the underlying iterators. 3006 func (itr *integerSortedMergeIterator) Stats() IteratorStats { 3007 var stats IteratorStats 3008 for _, input := range itr.inputs { 3009 stats.Add(input.Stats()) 3010 } 3011 return stats 3012 } 3013 3014 // Close closes the underlying iterators. 3015 func (itr *integerSortedMergeIterator) Close() error { 3016 for _, input := range itr.inputs { 3017 input.Close() 3018 } 3019 return nil 3020 } 3021 3022 // Next returns the next points from the iterator. 3023 func (itr *integerSortedMergeIterator) Next() (*IntegerPoint, error) { return itr.pop() } 3024 3025 // pop returns the next point from the heap. 3026 // Reads the next point from item's cursor and puts it back on the heap. 3027 func (itr *integerSortedMergeIterator) pop() (*IntegerPoint, error) { 3028 // Initialize the heap. See the MergeIterator to see why this has to be done lazily. 3029 if !itr.init { 3030 items := itr.heap.items 3031 itr.heap.items = make([]*integerSortedMergeHeapItem, 0, len(items)) 3032 for _, item := range items { 3033 var err error 3034 if item.point, err = item.itr.Next(); err != nil { 3035 return nil, err 3036 } else if item.point == nil { 3037 continue 3038 } 3039 itr.heap.items = append(itr.heap.items, item) 3040 } 3041 heap.Init(itr.heap) 3042 itr.init = true 3043 } 3044 3045 if len(itr.heap.items) == 0 { 3046 return nil, nil 3047 } 3048 3049 // Read the next item from the heap. 3050 item := heap.Pop(itr.heap).(*integerSortedMergeHeapItem) 3051 if item.err != nil { 3052 return nil, item.err 3053 } else if item.point == nil { 3054 return nil, nil 3055 } 3056 3057 // Copy the point for return. 3058 p := item.point.Clone() 3059 3060 // Read the next item from the cursor. Push back to heap if one exists. 3061 if item.point, item.err = item.itr.Next(); item.point != nil { 3062 heap.Push(itr.heap, item) 3063 } 3064 3065 return p, nil 3066 } 3067 3068 // integerSortedMergeHeap represents a heap of integerSortedMergeHeapItems. 3069 // Items are sorted with the following priority: 3070 // - By their measurement name; 3071 // - By their tag keys/values; 3072 // - By time; or 3073 // - By their Aux field values. 3074 type integerSortedMergeHeap struct { 3075 opt IteratorOptions 3076 items []*integerSortedMergeHeapItem 3077 } 3078 3079 func (h *integerSortedMergeHeap) Len() int { return len(h.items) } 3080 func (h *integerSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] } 3081 func (h *integerSortedMergeHeap) Less(i, j int) bool { 3082 x, y := h.items[i].point, h.items[j].point 3083 3084 if h.opt.Ascending { 3085 if x.Name != y.Name { 3086 return x.Name < y.Name 3087 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) { 3088 return xTags.ID() < yTags.ID() 3089 } 3090 3091 if x.Time != y.Time { 3092 return x.Time < y.Time 3093 } 3094 3095 if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) { 3096 for i := 0; i < len(x.Aux); i++ { 3097 v1, ok1 := x.Aux[i].(string) 3098 v2, ok2 := y.Aux[i].(string) 3099 if !ok1 || !ok2 { 3100 // Unsupported types used in Aux fields. Maybe they 3101 // need to be added here? 3102 return false 3103 } else if v1 == v2 { 3104 continue 3105 } 3106 return v1 < v2 3107 } 3108 } 3109 return false // Times and/or Aux fields are equal. 3110 } 3111 3112 if x.Name != y.Name { 3113 return x.Name > y.Name 3114 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) { 3115 return xTags.ID() > yTags.ID() 3116 } 3117 3118 if x.Time != y.Time { 3119 return x.Time > y.Time 3120 } 3121 3122 if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) { 3123 for i := 0; i < len(x.Aux); i++ { 3124 v1, ok1 := x.Aux[i].(string) 3125 v2, ok2 := y.Aux[i].(string) 3126 if !ok1 || !ok2 { 3127 // Unsupported types used in Aux fields. Maybe they 3128 // need to be added here? 3129 return false 3130 } else if v1 == v2 { 3131 continue 3132 } 3133 return v1 > v2 3134 } 3135 } 3136 return false // Times and/or Aux fields are equal. 3137 } 3138 3139 func (h *integerSortedMergeHeap) Push(x interface{}) { 3140 h.items = append(h.items, x.(*integerSortedMergeHeapItem)) 3141 } 3142 3143 func (h *integerSortedMergeHeap) Pop() interface{} { 3144 old := h.items 3145 n := len(old) 3146 item := old[n-1] 3147 h.items = old[0 : n-1] 3148 return item 3149 } 3150 3151 type integerSortedMergeHeapItem struct { 3152 point *IntegerPoint 3153 err error 3154 itr IntegerIterator 3155 } 3156 3157 // integerIteratorScanner scans the results of a IntegerIterator into a map. 3158 type integerIteratorScanner struct { 3159 input *bufIntegerIterator 3160 err error 3161 keys []influxql.VarRef 3162 defaultValue interface{} 3163 } 3164 3165 // newIntegerIteratorScanner creates a new IteratorScanner. 3166 func newIntegerIteratorScanner(input IntegerIterator, keys []influxql.VarRef, defaultValue interface{}) *integerIteratorScanner { 3167 return &integerIteratorScanner{ 3168 input: newBufIntegerIterator(input), 3169 keys: keys, 3170 defaultValue: defaultValue, 3171 } 3172 } 3173 3174 func (s *integerIteratorScanner) Peek() (int64, string, Tags) { 3175 if s.err != nil { 3176 return ZeroTime, "", Tags{} 3177 } 3178 3179 p, err := s.input.peek() 3180 if err != nil { 3181 s.err = err 3182 return ZeroTime, "", Tags{} 3183 } else if p == nil { 3184 return ZeroTime, "", Tags{} 3185 } 3186 return p.Time, p.Name, p.Tags 3187 } 3188 3189 func (s *integerIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) { 3190 if s.err != nil { 3191 return 3192 } 3193 3194 p, err := s.input.Next() 3195 if err != nil { 3196 s.err = err 3197 return 3198 } else if p == nil { 3199 s.useDefaults(m) 3200 return 3201 } else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) { 3202 s.useDefaults(m) 3203 s.input.unread(p) 3204 return 3205 } 3206 3207 if k := s.keys[0]; k.Val != "" { 3208 if p.Nil { 3209 if s.defaultValue != SkipDefault { 3210 m[k.Val] = castToType(s.defaultValue, k.Type) 3211 } 3212 } else { 3213 m[k.Val] = p.Value 3214 } 3215 } 3216 for i, v := range p.Aux { 3217 k := s.keys[i+1] 3218 switch v.(type) { 3219 case float64, int64, uint64, string, bool: 3220 m[k.Val] = v 3221 default: 3222 // Insert the fill value if one was specified. 3223 if s.defaultValue != SkipDefault { 3224 m[k.Val] = castToType(s.defaultValue, k.Type) 3225 } 3226 } 3227 } 3228 } 3229 3230 func (s *integerIteratorScanner) useDefaults(m map[string]interface{}) { 3231 if s.defaultValue == SkipDefault { 3232 return 3233 } 3234 for _, k := range s.keys { 3235 if k.Val == "" { 3236 continue 3237 } 3238 m[k.Val] = castToType(s.defaultValue, k.Type) 3239 } 3240 } 3241 3242 func (s *integerIteratorScanner) Stats() IteratorStats { return s.input.Stats() } 3243 func (s *integerIteratorScanner) Err() error { return s.err } 3244 func (s *integerIteratorScanner) Close() error { return s.input.Close() } 3245 3246 // integerParallelIterator represents an iterator that pulls data in a separate goroutine. 3247 type integerParallelIterator struct { 3248 input IntegerIterator 3249 ch chan integerPointError 3250 3251 once sync.Once 3252 closing chan struct{} 3253 wg sync.WaitGroup 3254 } 3255 3256 // newIntegerParallelIterator returns a new instance of integerParallelIterator. 3257 func newIntegerParallelIterator(input IntegerIterator) *integerParallelIterator { 3258 itr := &integerParallelIterator{ 3259 input: input, 3260 ch: make(chan integerPointError, 256), 3261 closing: make(chan struct{}), 3262 } 3263 itr.wg.Add(1) 3264 go itr.monitor() 3265 return itr 3266 } 3267 3268 // Stats returns stats from the underlying iterator. 3269 func (itr *integerParallelIterator) Stats() IteratorStats { return itr.input.Stats() } 3270 3271 // Close closes the underlying iterators. 3272 func (itr *integerParallelIterator) Close() error { 3273 itr.once.Do(func() { close(itr.closing) }) 3274 itr.wg.Wait() 3275 return itr.input.Close() 3276 } 3277 3278 // Next returns the next point from the iterator. 3279 func (itr *integerParallelIterator) Next() (*IntegerPoint, error) { 3280 v, ok := <-itr.ch 3281 if !ok { 3282 return nil, io.EOF 3283 } 3284 return v.point, v.err 3285 } 3286 3287 // monitor runs in a separate goroutine and actively pulls the next point. 3288 func (itr *integerParallelIterator) monitor() { 3289 defer close(itr.ch) 3290 defer itr.wg.Done() 3291 3292 for { 3293 // Read next point. 3294 p, err := itr.input.Next() 3295 if p != nil { 3296 p = p.Clone() 3297 } 3298 3299 select { 3300 case <-itr.closing: 3301 return 3302 case itr.ch <- integerPointError{point: p, err: err}: 3303 } 3304 } 3305 } 3306 3307 type integerPointError struct { 3308 point *IntegerPoint 3309 err error 3310 } 3311 3312 // integerLimitIterator represents an iterator that limits points per group. 3313 type integerLimitIterator struct { 3314 input IntegerIterator 3315 opt IteratorOptions 3316 n int 3317 3318 prev struct { 3319 name string 3320 tags Tags 3321 } 3322 } 3323 3324 // newIntegerLimitIterator returns a new instance of integerLimitIterator. 3325 func newIntegerLimitIterator(input IntegerIterator, opt IteratorOptions) *integerLimitIterator { 3326 return &integerLimitIterator{ 3327 input: input, 3328 opt: opt, 3329 } 3330 } 3331 3332 // Stats returns stats from the underlying iterator. 3333 func (itr *integerLimitIterator) Stats() IteratorStats { return itr.input.Stats() } 3334 3335 // Close closes the underlying iterators. 3336 func (itr *integerLimitIterator) Close() error { return itr.input.Close() } 3337 3338 // Next returns the next point from the iterator. 3339 func (itr *integerLimitIterator) Next() (*IntegerPoint, error) { 3340 for { 3341 p, err := itr.input.Next() 3342 if p == nil || err != nil { 3343 return nil, err 3344 } 3345 3346 // Reset window and counter if a new window is encountered. 3347 if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) { 3348 itr.prev.name = p.Name 3349 itr.prev.tags = p.Tags 3350 itr.n = 0 3351 } 3352 3353 // Increment counter. 3354 itr.n++ 3355 3356 // Read next point if not beyond the offset. 3357 if itr.n <= itr.opt.Offset { 3358 continue 3359 } 3360 3361 // Read next point if we're beyond the limit. 3362 if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit { 3363 continue 3364 } 3365 3366 return p, nil 3367 } 3368 } 3369 3370 type integerFillIterator struct { 3371 input *bufIntegerIterator 3372 prev IntegerPoint 3373 startTime int64 3374 endTime int64 3375 auxFields []interface{} 3376 init bool 3377 opt IteratorOptions 3378 3379 window struct { 3380 name string 3381 tags Tags 3382 time int64 3383 offset int64 3384 } 3385 } 3386 3387 func newIntegerFillIterator(input IntegerIterator, expr influxql.Expr, opt IteratorOptions) *integerFillIterator { 3388 if opt.Fill == influxql.NullFill { 3389 if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" { 3390 opt.Fill = influxql.NumberFill 3391 opt.FillValue = int64(0) 3392 } 3393 } 3394 3395 var startTime, endTime int64 3396 if opt.Ascending { 3397 startTime, _ = opt.Window(opt.StartTime) 3398 endTime, _ = opt.Window(opt.EndTime) 3399 } else { 3400 startTime, _ = opt.Window(opt.EndTime) 3401 endTime, _ = opt.Window(opt.StartTime) 3402 } 3403 3404 var auxFields []interface{} 3405 if len(opt.Aux) > 0 { 3406 auxFields = make([]interface{}, len(opt.Aux)) 3407 } 3408 3409 return &integerFillIterator{ 3410 input: newBufIntegerIterator(input), 3411 prev: IntegerPoint{Nil: true}, 3412 startTime: startTime, 3413 endTime: endTime, 3414 auxFields: auxFields, 3415 opt: opt, 3416 } 3417 } 3418 3419 func (itr *integerFillIterator) Stats() IteratorStats { return itr.input.Stats() } 3420 func (itr *integerFillIterator) Close() error { return itr.input.Close() } 3421 3422 func (itr *integerFillIterator) Next() (*IntegerPoint, error) { 3423 if !itr.init { 3424 p, err := itr.input.peek() 3425 if p == nil || err != nil { 3426 return nil, err 3427 } 3428 itr.window.name, itr.window.tags = p.Name, p.Tags 3429 itr.window.time = itr.startTime 3430 if itr.startTime == influxql.MinTime { 3431 itr.window.time, _ = itr.opt.Window(p.Time) 3432 } 3433 if itr.opt.Location != nil { 3434 _, itr.window.offset = itr.opt.Zone(itr.window.time) 3435 } 3436 itr.init = true 3437 } 3438 3439 p, err := itr.input.Next() 3440 if err != nil { 3441 return nil, err 3442 } 3443 3444 // Check if the next point is outside of our window or is nil. 3445 if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() { 3446 // If we are inside of an interval, unread the point and continue below to 3447 // constructing a new point. 3448 if itr.opt.Ascending && itr.window.time <= itr.endTime { 3449 itr.input.unread(p) 3450 p = nil 3451 goto CONSTRUCT 3452 } else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime { 3453 itr.input.unread(p) 3454 p = nil 3455 goto CONSTRUCT 3456 } 3457 3458 // We are *not* in a current interval. If there is no next point, 3459 // we are at the end of all intervals. 3460 if p == nil { 3461 return nil, nil 3462 } 3463 3464 // Set the new interval. 3465 itr.window.name, itr.window.tags = p.Name, p.Tags 3466 itr.window.time = itr.startTime 3467 if itr.window.time == influxql.MinTime { 3468 itr.window.time, _ = itr.opt.Window(p.Time) 3469 } 3470 if itr.opt.Location != nil { 3471 _, itr.window.offset = itr.opt.Zone(itr.window.time) 3472 } 3473 itr.prev = IntegerPoint{Nil: true} 3474 } 3475 3476 // Check if the point is our next expected point. 3477 CONSTRUCT: 3478 if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) { 3479 if p != nil { 3480 itr.input.unread(p) 3481 } 3482 3483 p = &IntegerPoint{ 3484 Name: itr.window.name, 3485 Tags: itr.window.tags, 3486 Time: itr.window.time, 3487 Aux: itr.auxFields, 3488 } 3489 3490 switch itr.opt.Fill { 3491 case influxql.LinearFill: 3492 if !itr.prev.Nil { 3493 next, err := itr.input.peek() 3494 if err != nil { 3495 return nil, err 3496 } else if next != nil && next.Name == itr.window.name && next.Tags.ID() == itr.window.tags.ID() { 3497 interval := int64(itr.opt.Interval.Duration) 3498 start := itr.window.time / interval 3499 p.Value = linearInteger(start, itr.prev.Time/interval, next.Time/interval, itr.prev.Value, next.Value) 3500 } else { 3501 p.Nil = true 3502 } 3503 } else { 3504 p.Nil = true 3505 } 3506 3507 case influxql.NullFill: 3508 p.Nil = true 3509 case influxql.NumberFill: 3510 p.Value, _ = castToInteger(itr.opt.FillValue) 3511 case influxql.PreviousFill: 3512 if !itr.prev.Nil { 3513 p.Value = itr.prev.Value 3514 p.Nil = itr.prev.Nil 3515 } else { 3516 p.Nil = true 3517 } 3518 } 3519 } else { 3520 itr.prev = *p 3521 } 3522 3523 // Advance the expected time. Do not advance to a new window here 3524 // as there may be lingering points with the same timestamp in the previous 3525 // window. 3526 if itr.opt.Ascending { 3527 itr.window.time += int64(itr.opt.Interval.Duration) 3528 } else { 3529 itr.window.time -= int64(itr.opt.Interval.Duration) 3530 } 3531 3532 // Check to see if we have passed over an offset change and adjust the time 3533 // to account for this new offset. 3534 if itr.opt.Location != nil { 3535 if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset { 3536 diff := itr.window.offset - offset 3537 if abs(diff) < int64(itr.opt.Interval.Duration) { 3538 itr.window.time += diff 3539 } 3540 itr.window.offset = offset 3541 } 3542 } 3543 return p, nil 3544 } 3545 3546 // integerIntervalIterator represents a integer implementation of IntervalIterator. 3547 type integerIntervalIterator struct { 3548 input IntegerIterator 3549 opt IteratorOptions 3550 } 3551 3552 func newIntegerIntervalIterator(input IntegerIterator, opt IteratorOptions) *integerIntervalIterator { 3553 return &integerIntervalIterator{input: input, opt: opt} 3554 } 3555 3556 func (itr *integerIntervalIterator) Stats() IteratorStats { return itr.input.Stats() } 3557 func (itr *integerIntervalIterator) Close() error { return itr.input.Close() } 3558 3559 func (itr *integerIntervalIterator) Next() (*IntegerPoint, error) { 3560 p, err := itr.input.Next() 3561 if p == nil || err != nil { 3562 return nil, err 3563 } 3564 p.Time, _ = itr.opt.Window(p.Time) 3565 // If we see the minimum allowable time, set the time to zero so we don't 3566 // break the default returned time for aggregate queries without times. 3567 if p.Time == influxql.MinTime { 3568 p.Time = 0 3569 } 3570 return p, nil 3571 } 3572 3573 // integerInterruptIterator represents a integer implementation of InterruptIterator. 3574 type integerInterruptIterator struct { 3575 input IntegerIterator 3576 closing <-chan struct{} 3577 count int 3578 } 3579 3580 func newIntegerInterruptIterator(input IntegerIterator, closing <-chan struct{}) *integerInterruptIterator { 3581 return &integerInterruptIterator{input: input, closing: closing} 3582 } 3583 3584 func (itr *integerInterruptIterator) Stats() IteratorStats { return itr.input.Stats() } 3585 func (itr *integerInterruptIterator) Close() error { return itr.input.Close() } 3586 3587 func (itr *integerInterruptIterator) Next() (*IntegerPoint, error) { 3588 // Only check if the channel is closed every N points. This 3589 // intentionally checks on both 0 and N so that if the iterator 3590 // has been interrupted before the first point is emitted it will 3591 // not emit any points. 3592 if itr.count&0xFF == 0xFF { 3593 select { 3594 case <-itr.closing: 3595 return nil, itr.Close() 3596 default: 3597 // Reset iterator count to zero and fall through to emit the next point. 3598 itr.count = 0 3599 } 3600 } 3601 3602 // Increment the counter for every point read. 3603 itr.count++ 3604 return itr.input.Next() 3605 } 3606 3607 // integerCloseInterruptIterator represents a integer implementation of CloseInterruptIterator. 3608 type integerCloseInterruptIterator struct { 3609 input IntegerIterator 3610 closing <-chan struct{} 3611 done chan struct{} 3612 once sync.Once 3613 } 3614 3615 func newIntegerCloseInterruptIterator(input IntegerIterator, closing <-chan struct{}) *integerCloseInterruptIterator { 3616 itr := &integerCloseInterruptIterator{ 3617 input: input, 3618 closing: closing, 3619 done: make(chan struct{}), 3620 } 3621 go itr.monitor() 3622 return itr 3623 } 3624 3625 func (itr *integerCloseInterruptIterator) monitor() { 3626 select { 3627 case <-itr.closing: 3628 itr.Close() 3629 case <-itr.done: 3630 } 3631 } 3632 3633 func (itr *integerCloseInterruptIterator) Stats() IteratorStats { 3634 return itr.input.Stats() 3635 } 3636 3637 func (itr *integerCloseInterruptIterator) Close() error { 3638 itr.once.Do(func() { 3639 close(itr.done) 3640 itr.input.Close() 3641 }) 3642 return nil 3643 } 3644 3645 func (itr *integerCloseInterruptIterator) Next() (*IntegerPoint, error) { 3646 p, err := itr.input.Next() 3647 if err != nil { 3648 // Check if the iterator was closed. 3649 select { 3650 case <-itr.done: 3651 return nil, nil 3652 default: 3653 return nil, err 3654 } 3655 } 3656 return p, nil 3657 } 3658 3659 // integerReduceFloatIterator executes a reducer for every interval and buffers the result. 3660 type integerReduceFloatIterator struct { 3661 input *bufIntegerIterator 3662 create func() (IntegerPointAggregator, FloatPointEmitter) 3663 dims []string 3664 opt IteratorOptions 3665 points []FloatPoint 3666 keepTags bool 3667 } 3668 3669 func newIntegerReduceFloatIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, FloatPointEmitter)) *integerReduceFloatIterator { 3670 return &integerReduceFloatIterator{ 3671 input: newBufIntegerIterator(input), 3672 create: createFn, 3673 dims: opt.GetDimensions(), 3674 opt: opt, 3675 } 3676 } 3677 3678 // Stats returns stats from the input iterator. 3679 func (itr *integerReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() } 3680 3681 // Close closes the iterator and all child iterators. 3682 func (itr *integerReduceFloatIterator) Close() error { return itr.input.Close() } 3683 3684 // Next returns the minimum value for the next available interval. 3685 func (itr *integerReduceFloatIterator) Next() (*FloatPoint, error) { 3686 // Calculate next window if we have no more points. 3687 if len(itr.points) == 0 { 3688 var err error 3689 itr.points, err = itr.reduce() 3690 if len(itr.points) == 0 { 3691 return nil, err 3692 } 3693 } 3694 3695 // Pop next point off the stack. 3696 p := &itr.points[len(itr.points)-1] 3697 itr.points = itr.points[:len(itr.points)-1] 3698 return p, nil 3699 } 3700 3701 // integerReduceFloatPoint stores the reduced data for a name/tag combination. 3702 type integerReduceFloatPoint struct { 3703 Name string 3704 Tags Tags 3705 Aggregator IntegerPointAggregator 3706 Emitter FloatPointEmitter 3707 } 3708 3709 // reduce executes fn once for every point in the next window. 3710 // The previous value for the dimension is passed to fn. 3711 func (itr *integerReduceFloatIterator) reduce() ([]FloatPoint, error) { 3712 // Calculate next window. 3713 var ( 3714 startTime, endTime int64 3715 window struct { 3716 name string 3717 tags string 3718 } 3719 ) 3720 for { 3721 p, err := itr.input.Next() 3722 if err != nil || p == nil { 3723 return nil, err 3724 } else if p.Nil { 3725 continue 3726 } 3727 3728 // Unread the point so it can be processed. 3729 itr.input.unread(p) 3730 startTime, endTime = itr.opt.Window(p.Time) 3731 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 3732 break 3733 } 3734 3735 // Create points by tags. 3736 m := make(map[string]*integerReduceFloatPoint) 3737 for { 3738 // Read next point. 3739 curr, err := itr.input.NextInWindow(startTime, endTime) 3740 if err != nil { 3741 return nil, err 3742 } else if curr == nil { 3743 break 3744 } else if curr.Nil { 3745 continue 3746 } else if curr.Name != window.name { 3747 itr.input.unread(curr) 3748 break 3749 } 3750 3751 // Ensure this point is within the same final window. 3752 if curr.Name != window.name { 3753 itr.input.unread(curr) 3754 break 3755 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 3756 itr.input.unread(curr) 3757 break 3758 } 3759 3760 // Retrieve the tags on this point for this level of the query. 3761 // This may be different than the bucket dimensions. 3762 tags := curr.Tags.Subset(itr.dims) 3763 id := tags.ID() 3764 3765 // Retrieve the aggregator for this name/tag combination or create one. 3766 rp := m[id] 3767 if rp == nil { 3768 aggregator, emitter := itr.create() 3769 rp = &integerReduceFloatPoint{ 3770 Name: curr.Name, 3771 Tags: tags, 3772 Aggregator: aggregator, 3773 Emitter: emitter, 3774 } 3775 m[id] = rp 3776 } 3777 rp.Aggregator.AggregateInteger(curr) 3778 } 3779 3780 keys := make([]string, 0, len(m)) 3781 for k := range m { 3782 keys = append(keys, k) 3783 } 3784 3785 // Reverse sort points by name & tag. 3786 // This ensures a consistent order of output. 3787 if len(keys) > 0 { 3788 var sorted sort.Interface = sort.StringSlice(keys) 3789 if itr.opt.Ascending { 3790 sorted = sort.Reverse(sorted) 3791 } 3792 sort.Sort(sorted) 3793 } 3794 3795 // Assume the points are already sorted until proven otherwise. 3796 sortedByTime := true 3797 // Emit the points for each name & tag combination. 3798 a := make([]FloatPoint, 0, len(m)) 3799 for _, k := range keys { 3800 rp := m[k] 3801 points := rp.Emitter.Emit() 3802 for i := len(points) - 1; i >= 0; i-- { 3803 points[i].Name = rp.Name 3804 if !itr.keepTags { 3805 points[i].Tags = rp.Tags 3806 } 3807 // Set the points time to the interval time if the reducer didn't provide one. 3808 if points[i].Time == ZeroTime { 3809 points[i].Time = startTime 3810 } else { 3811 sortedByTime = false 3812 } 3813 a = append(a, points[i]) 3814 } 3815 } 3816 // Points may be out of order. Perform a stable sort by time if requested. 3817 if !sortedByTime && itr.opt.Ordered { 3818 var sorted sort.Interface = floatPointsByTime(a) 3819 if itr.opt.Ascending { 3820 sorted = sort.Reverse(sorted) 3821 } 3822 sort.Stable(sorted) 3823 } 3824 return a, nil 3825 } 3826 3827 // integerStreamFloatIterator streams inputs into the iterator and emits points gradually. 3828 type integerStreamFloatIterator struct { 3829 input *bufIntegerIterator 3830 create func() (IntegerPointAggregator, FloatPointEmitter) 3831 dims []string 3832 opt IteratorOptions 3833 m map[string]*integerReduceFloatPoint 3834 points []FloatPoint 3835 } 3836 3837 // newIntegerStreamFloatIterator returns a new instance of integerStreamFloatIterator. 3838 func newIntegerStreamFloatIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, FloatPointEmitter), opt IteratorOptions) *integerStreamFloatIterator { 3839 return &integerStreamFloatIterator{ 3840 input: newBufIntegerIterator(input), 3841 create: createFn, 3842 dims: opt.GetDimensions(), 3843 opt: opt, 3844 m: make(map[string]*integerReduceFloatPoint), 3845 } 3846 } 3847 3848 // Stats returns stats from the input iterator. 3849 func (itr *integerStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() } 3850 3851 // Close closes the iterator and all child iterators. 3852 func (itr *integerStreamFloatIterator) Close() error { return itr.input.Close() } 3853 3854 // Next returns the next value for the stream iterator. 3855 func (itr *integerStreamFloatIterator) Next() (*FloatPoint, error) { 3856 // Calculate next window if we have no more points. 3857 if len(itr.points) == 0 { 3858 var err error 3859 itr.points, err = itr.reduce() 3860 if len(itr.points) == 0 { 3861 return nil, err 3862 } 3863 } 3864 3865 // Pop next point off the stack. 3866 p := &itr.points[len(itr.points)-1] 3867 itr.points = itr.points[:len(itr.points)-1] 3868 return p, nil 3869 } 3870 3871 // reduce creates and manages aggregators for every point from the input. 3872 // After aggregating a point, it always tries to emit a value using the emitter. 3873 func (itr *integerStreamFloatIterator) reduce() ([]FloatPoint, error) { 3874 // We have already read all of the input points. 3875 if itr.m == nil { 3876 return nil, nil 3877 } 3878 3879 for { 3880 // Read next point. 3881 curr, err := itr.input.Next() 3882 if err != nil { 3883 return nil, err 3884 } else if curr == nil { 3885 // Close all of the aggregators to flush any remaining points to emit. 3886 var points []FloatPoint 3887 for _, rp := range itr.m { 3888 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 3889 if err := aggregator.Close(); err != nil { 3890 return nil, err 3891 } 3892 3893 pts := rp.Emitter.Emit() 3894 if len(pts) == 0 { 3895 continue 3896 } 3897 3898 for i := range pts { 3899 pts[i].Name = rp.Name 3900 pts[i].Tags = rp.Tags 3901 } 3902 points = append(points, pts...) 3903 } 3904 } 3905 3906 // Eliminate the aggregators and emitters. 3907 itr.m = nil 3908 return points, nil 3909 } else if curr.Nil { 3910 continue 3911 } 3912 tags := curr.Tags.Subset(itr.dims) 3913 3914 id := curr.Name 3915 if len(tags.m) > 0 { 3916 id += "\x00" + tags.ID() 3917 } 3918 3919 // Retrieve the aggregator for this name/tag combination or create one. 3920 rp := itr.m[id] 3921 if rp == nil { 3922 aggregator, emitter := itr.create() 3923 rp = &integerReduceFloatPoint{ 3924 Name: curr.Name, 3925 Tags: tags, 3926 Aggregator: aggregator, 3927 Emitter: emitter, 3928 } 3929 itr.m[id] = rp 3930 } 3931 rp.Aggregator.AggregateInteger(curr) 3932 3933 // Attempt to emit points from the aggregator. 3934 points := rp.Emitter.Emit() 3935 if len(points) == 0 { 3936 continue 3937 } 3938 3939 for i := range points { 3940 points[i].Name = rp.Name 3941 points[i].Tags = rp.Tags 3942 } 3943 return points, nil 3944 } 3945 } 3946 3947 // integerReduceIntegerIterator executes a reducer for every interval and buffers the result. 3948 type integerReduceIntegerIterator struct { 3949 input *bufIntegerIterator 3950 create func() (IntegerPointAggregator, IntegerPointEmitter) 3951 dims []string 3952 opt IteratorOptions 3953 points []IntegerPoint 3954 keepTags bool 3955 } 3956 3957 func newIntegerReduceIntegerIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, IntegerPointEmitter)) *integerReduceIntegerIterator { 3958 return &integerReduceIntegerIterator{ 3959 input: newBufIntegerIterator(input), 3960 create: createFn, 3961 dims: opt.GetDimensions(), 3962 opt: opt, 3963 } 3964 } 3965 3966 // Stats returns stats from the input iterator. 3967 func (itr *integerReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() } 3968 3969 // Close closes the iterator and all child iterators. 3970 func (itr *integerReduceIntegerIterator) Close() error { return itr.input.Close() } 3971 3972 // Next returns the minimum value for the next available interval. 3973 func (itr *integerReduceIntegerIterator) Next() (*IntegerPoint, error) { 3974 // Calculate next window if we have no more points. 3975 if len(itr.points) == 0 { 3976 var err error 3977 itr.points, err = itr.reduce() 3978 if len(itr.points) == 0 { 3979 return nil, err 3980 } 3981 } 3982 3983 // Pop next point off the stack. 3984 p := &itr.points[len(itr.points)-1] 3985 itr.points = itr.points[:len(itr.points)-1] 3986 return p, nil 3987 } 3988 3989 // integerReduceIntegerPoint stores the reduced data for a name/tag combination. 3990 type integerReduceIntegerPoint struct { 3991 Name string 3992 Tags Tags 3993 Aggregator IntegerPointAggregator 3994 Emitter IntegerPointEmitter 3995 } 3996 3997 // reduce executes fn once for every point in the next window. 3998 // The previous value for the dimension is passed to fn. 3999 func (itr *integerReduceIntegerIterator) reduce() ([]IntegerPoint, error) { 4000 // Calculate next window. 4001 var ( 4002 startTime, endTime int64 4003 window struct { 4004 name string 4005 tags string 4006 } 4007 ) 4008 for { 4009 p, err := itr.input.Next() 4010 if err != nil || p == nil { 4011 return nil, err 4012 } else if p.Nil { 4013 continue 4014 } 4015 4016 // Unread the point so it can be processed. 4017 itr.input.unread(p) 4018 startTime, endTime = itr.opt.Window(p.Time) 4019 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 4020 break 4021 } 4022 4023 // Create points by tags. 4024 m := make(map[string]*integerReduceIntegerPoint) 4025 for { 4026 // Read next point. 4027 curr, err := itr.input.NextInWindow(startTime, endTime) 4028 if err != nil { 4029 return nil, err 4030 } else if curr == nil { 4031 break 4032 } else if curr.Nil { 4033 continue 4034 } else if curr.Name != window.name { 4035 itr.input.unread(curr) 4036 break 4037 } 4038 4039 // Ensure this point is within the same final window. 4040 if curr.Name != window.name { 4041 itr.input.unread(curr) 4042 break 4043 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 4044 itr.input.unread(curr) 4045 break 4046 } 4047 4048 // Retrieve the tags on this point for this level of the query. 4049 // This may be different than the bucket dimensions. 4050 tags := curr.Tags.Subset(itr.dims) 4051 id := tags.ID() 4052 4053 // Retrieve the aggregator for this name/tag combination or create one. 4054 rp := m[id] 4055 if rp == nil { 4056 aggregator, emitter := itr.create() 4057 rp = &integerReduceIntegerPoint{ 4058 Name: curr.Name, 4059 Tags: tags, 4060 Aggregator: aggregator, 4061 Emitter: emitter, 4062 } 4063 m[id] = rp 4064 } 4065 rp.Aggregator.AggregateInteger(curr) 4066 } 4067 4068 keys := make([]string, 0, len(m)) 4069 for k := range m { 4070 keys = append(keys, k) 4071 } 4072 4073 // Reverse sort points by name & tag. 4074 // This ensures a consistent order of output. 4075 if len(keys) > 0 { 4076 var sorted sort.Interface = sort.StringSlice(keys) 4077 if itr.opt.Ascending { 4078 sorted = sort.Reverse(sorted) 4079 } 4080 sort.Sort(sorted) 4081 } 4082 4083 // Assume the points are already sorted until proven otherwise. 4084 sortedByTime := true 4085 // Emit the points for each name & tag combination. 4086 a := make([]IntegerPoint, 0, len(m)) 4087 for _, k := range keys { 4088 rp := m[k] 4089 points := rp.Emitter.Emit() 4090 for i := len(points) - 1; i >= 0; i-- { 4091 points[i].Name = rp.Name 4092 if !itr.keepTags { 4093 points[i].Tags = rp.Tags 4094 } 4095 // Set the points time to the interval time if the reducer didn't provide one. 4096 if points[i].Time == ZeroTime { 4097 points[i].Time = startTime 4098 } else { 4099 sortedByTime = false 4100 } 4101 a = append(a, points[i]) 4102 } 4103 } 4104 // Points may be out of order. Perform a stable sort by time if requested. 4105 if !sortedByTime && itr.opt.Ordered { 4106 var sorted sort.Interface = integerPointsByTime(a) 4107 if itr.opt.Ascending { 4108 sorted = sort.Reverse(sorted) 4109 } 4110 sort.Stable(sorted) 4111 } 4112 return a, nil 4113 } 4114 4115 // integerStreamIntegerIterator streams inputs into the iterator and emits points gradually. 4116 type integerStreamIntegerIterator struct { 4117 input *bufIntegerIterator 4118 create func() (IntegerPointAggregator, IntegerPointEmitter) 4119 dims []string 4120 opt IteratorOptions 4121 m map[string]*integerReduceIntegerPoint 4122 points []IntegerPoint 4123 } 4124 4125 // newIntegerStreamIntegerIterator returns a new instance of integerStreamIntegerIterator. 4126 func newIntegerStreamIntegerIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, IntegerPointEmitter), opt IteratorOptions) *integerStreamIntegerIterator { 4127 return &integerStreamIntegerIterator{ 4128 input: newBufIntegerIterator(input), 4129 create: createFn, 4130 dims: opt.GetDimensions(), 4131 opt: opt, 4132 m: make(map[string]*integerReduceIntegerPoint), 4133 } 4134 } 4135 4136 // Stats returns stats from the input iterator. 4137 func (itr *integerStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() } 4138 4139 // Close closes the iterator and all child iterators. 4140 func (itr *integerStreamIntegerIterator) Close() error { return itr.input.Close() } 4141 4142 // Next returns the next value for the stream iterator. 4143 func (itr *integerStreamIntegerIterator) Next() (*IntegerPoint, error) { 4144 // Calculate next window if we have no more points. 4145 if len(itr.points) == 0 { 4146 var err error 4147 itr.points, err = itr.reduce() 4148 if len(itr.points) == 0 { 4149 return nil, err 4150 } 4151 } 4152 4153 // Pop next point off the stack. 4154 p := &itr.points[len(itr.points)-1] 4155 itr.points = itr.points[:len(itr.points)-1] 4156 return p, nil 4157 } 4158 4159 // reduce creates and manages aggregators for every point from the input. 4160 // After aggregating a point, it always tries to emit a value using the emitter. 4161 func (itr *integerStreamIntegerIterator) reduce() ([]IntegerPoint, error) { 4162 // We have already read all of the input points. 4163 if itr.m == nil { 4164 return nil, nil 4165 } 4166 4167 for { 4168 // Read next point. 4169 curr, err := itr.input.Next() 4170 if err != nil { 4171 return nil, err 4172 } else if curr == nil { 4173 // Close all of the aggregators to flush any remaining points to emit. 4174 var points []IntegerPoint 4175 for _, rp := range itr.m { 4176 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 4177 if err := aggregator.Close(); err != nil { 4178 return nil, err 4179 } 4180 4181 pts := rp.Emitter.Emit() 4182 if len(pts) == 0 { 4183 continue 4184 } 4185 4186 for i := range pts { 4187 pts[i].Name = rp.Name 4188 pts[i].Tags = rp.Tags 4189 } 4190 points = append(points, pts...) 4191 } 4192 } 4193 4194 // Eliminate the aggregators and emitters. 4195 itr.m = nil 4196 return points, nil 4197 } else if curr.Nil { 4198 continue 4199 } 4200 tags := curr.Tags.Subset(itr.dims) 4201 4202 id := curr.Name 4203 if len(tags.m) > 0 { 4204 id += "\x00" + tags.ID() 4205 } 4206 4207 // Retrieve the aggregator for this name/tag combination or create one. 4208 rp := itr.m[id] 4209 if rp == nil { 4210 aggregator, emitter := itr.create() 4211 rp = &integerReduceIntegerPoint{ 4212 Name: curr.Name, 4213 Tags: tags, 4214 Aggregator: aggregator, 4215 Emitter: emitter, 4216 } 4217 itr.m[id] = rp 4218 } 4219 rp.Aggregator.AggregateInteger(curr) 4220 4221 // Attempt to emit points from the aggregator. 4222 points := rp.Emitter.Emit() 4223 if len(points) == 0 { 4224 continue 4225 } 4226 4227 for i := range points { 4228 points[i].Name = rp.Name 4229 points[i].Tags = rp.Tags 4230 } 4231 return points, nil 4232 } 4233 } 4234 4235 // integerReduceUnsignedIterator executes a reducer for every interval and buffers the result. 4236 type integerReduceUnsignedIterator struct { 4237 input *bufIntegerIterator 4238 create func() (IntegerPointAggregator, UnsignedPointEmitter) 4239 dims []string 4240 opt IteratorOptions 4241 points []UnsignedPoint 4242 keepTags bool 4243 } 4244 4245 func newIntegerReduceUnsignedIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, UnsignedPointEmitter)) *integerReduceUnsignedIterator { 4246 return &integerReduceUnsignedIterator{ 4247 input: newBufIntegerIterator(input), 4248 create: createFn, 4249 dims: opt.GetDimensions(), 4250 opt: opt, 4251 } 4252 } 4253 4254 // Stats returns stats from the input iterator. 4255 func (itr *integerReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() } 4256 4257 // Close closes the iterator and all child iterators. 4258 func (itr *integerReduceUnsignedIterator) Close() error { return itr.input.Close() } 4259 4260 // Next returns the minimum value for the next available interval. 4261 func (itr *integerReduceUnsignedIterator) Next() (*UnsignedPoint, error) { 4262 // Calculate next window if we have no more points. 4263 if len(itr.points) == 0 { 4264 var err error 4265 itr.points, err = itr.reduce() 4266 if len(itr.points) == 0 { 4267 return nil, err 4268 } 4269 } 4270 4271 // Pop next point off the stack. 4272 p := &itr.points[len(itr.points)-1] 4273 itr.points = itr.points[:len(itr.points)-1] 4274 return p, nil 4275 } 4276 4277 // integerReduceUnsignedPoint stores the reduced data for a name/tag combination. 4278 type integerReduceUnsignedPoint struct { 4279 Name string 4280 Tags Tags 4281 Aggregator IntegerPointAggregator 4282 Emitter UnsignedPointEmitter 4283 } 4284 4285 // reduce executes fn once for every point in the next window. 4286 // The previous value for the dimension is passed to fn. 4287 func (itr *integerReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) { 4288 // Calculate next window. 4289 var ( 4290 startTime, endTime int64 4291 window struct { 4292 name string 4293 tags string 4294 } 4295 ) 4296 for { 4297 p, err := itr.input.Next() 4298 if err != nil || p == nil { 4299 return nil, err 4300 } else if p.Nil { 4301 continue 4302 } 4303 4304 // Unread the point so it can be processed. 4305 itr.input.unread(p) 4306 startTime, endTime = itr.opt.Window(p.Time) 4307 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 4308 break 4309 } 4310 4311 // Create points by tags. 4312 m := make(map[string]*integerReduceUnsignedPoint) 4313 for { 4314 // Read next point. 4315 curr, err := itr.input.NextInWindow(startTime, endTime) 4316 if err != nil { 4317 return nil, err 4318 } else if curr == nil { 4319 break 4320 } else if curr.Nil { 4321 continue 4322 } else if curr.Name != window.name { 4323 itr.input.unread(curr) 4324 break 4325 } 4326 4327 // Ensure this point is within the same final window. 4328 if curr.Name != window.name { 4329 itr.input.unread(curr) 4330 break 4331 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 4332 itr.input.unread(curr) 4333 break 4334 } 4335 4336 // Retrieve the tags on this point for this level of the query. 4337 // This may be different than the bucket dimensions. 4338 tags := curr.Tags.Subset(itr.dims) 4339 id := tags.ID() 4340 4341 // Retrieve the aggregator for this name/tag combination or create one. 4342 rp := m[id] 4343 if rp == nil { 4344 aggregator, emitter := itr.create() 4345 rp = &integerReduceUnsignedPoint{ 4346 Name: curr.Name, 4347 Tags: tags, 4348 Aggregator: aggregator, 4349 Emitter: emitter, 4350 } 4351 m[id] = rp 4352 } 4353 rp.Aggregator.AggregateInteger(curr) 4354 } 4355 4356 keys := make([]string, 0, len(m)) 4357 for k := range m { 4358 keys = append(keys, k) 4359 } 4360 4361 // Reverse sort points by name & tag. 4362 // This ensures a consistent order of output. 4363 if len(keys) > 0 { 4364 var sorted sort.Interface = sort.StringSlice(keys) 4365 if itr.opt.Ascending { 4366 sorted = sort.Reverse(sorted) 4367 } 4368 sort.Sort(sorted) 4369 } 4370 4371 // Assume the points are already sorted until proven otherwise. 4372 sortedByTime := true 4373 // Emit the points for each name & tag combination. 4374 a := make([]UnsignedPoint, 0, len(m)) 4375 for _, k := range keys { 4376 rp := m[k] 4377 points := rp.Emitter.Emit() 4378 for i := len(points) - 1; i >= 0; i-- { 4379 points[i].Name = rp.Name 4380 if !itr.keepTags { 4381 points[i].Tags = rp.Tags 4382 } 4383 // Set the points time to the interval time if the reducer didn't provide one. 4384 if points[i].Time == ZeroTime { 4385 points[i].Time = startTime 4386 } else { 4387 sortedByTime = false 4388 } 4389 a = append(a, points[i]) 4390 } 4391 } 4392 // Points may be out of order. Perform a stable sort by time if requested. 4393 if !sortedByTime && itr.opt.Ordered { 4394 var sorted sort.Interface = unsignedPointsByTime(a) 4395 if itr.opt.Ascending { 4396 sorted = sort.Reverse(sorted) 4397 } 4398 sort.Stable(sorted) 4399 } 4400 return a, nil 4401 } 4402 4403 // integerStreamUnsignedIterator streams inputs into the iterator and emits points gradually. 4404 type integerStreamUnsignedIterator struct { 4405 input *bufIntegerIterator 4406 create func() (IntegerPointAggregator, UnsignedPointEmitter) 4407 dims []string 4408 opt IteratorOptions 4409 m map[string]*integerReduceUnsignedPoint 4410 points []UnsignedPoint 4411 } 4412 4413 // newIntegerStreamUnsignedIterator returns a new instance of integerStreamUnsignedIterator. 4414 func newIntegerStreamUnsignedIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *integerStreamUnsignedIterator { 4415 return &integerStreamUnsignedIterator{ 4416 input: newBufIntegerIterator(input), 4417 create: createFn, 4418 dims: opt.GetDimensions(), 4419 opt: opt, 4420 m: make(map[string]*integerReduceUnsignedPoint), 4421 } 4422 } 4423 4424 // Stats returns stats from the input iterator. 4425 func (itr *integerStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() } 4426 4427 // Close closes the iterator and all child iterators. 4428 func (itr *integerStreamUnsignedIterator) Close() error { return itr.input.Close() } 4429 4430 // Next returns the next value for the stream iterator. 4431 func (itr *integerStreamUnsignedIterator) Next() (*UnsignedPoint, error) { 4432 // Calculate next window if we have no more points. 4433 if len(itr.points) == 0 { 4434 var err error 4435 itr.points, err = itr.reduce() 4436 if len(itr.points) == 0 { 4437 return nil, err 4438 } 4439 } 4440 4441 // Pop next point off the stack. 4442 p := &itr.points[len(itr.points)-1] 4443 itr.points = itr.points[:len(itr.points)-1] 4444 return p, nil 4445 } 4446 4447 // reduce creates and manages aggregators for every point from the input. 4448 // After aggregating a point, it always tries to emit a value using the emitter. 4449 func (itr *integerStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) { 4450 // We have already read all of the input points. 4451 if itr.m == nil { 4452 return nil, nil 4453 } 4454 4455 for { 4456 // Read next point. 4457 curr, err := itr.input.Next() 4458 if err != nil { 4459 return nil, err 4460 } else if curr == nil { 4461 // Close all of the aggregators to flush any remaining points to emit. 4462 var points []UnsignedPoint 4463 for _, rp := range itr.m { 4464 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 4465 if err := aggregator.Close(); err != nil { 4466 return nil, err 4467 } 4468 4469 pts := rp.Emitter.Emit() 4470 if len(pts) == 0 { 4471 continue 4472 } 4473 4474 for i := range pts { 4475 pts[i].Name = rp.Name 4476 pts[i].Tags = rp.Tags 4477 } 4478 points = append(points, pts...) 4479 } 4480 } 4481 4482 // Eliminate the aggregators and emitters. 4483 itr.m = nil 4484 return points, nil 4485 } else if curr.Nil { 4486 continue 4487 } 4488 tags := curr.Tags.Subset(itr.dims) 4489 4490 id := curr.Name 4491 if len(tags.m) > 0 { 4492 id += "\x00" + tags.ID() 4493 } 4494 4495 // Retrieve the aggregator for this name/tag combination or create one. 4496 rp := itr.m[id] 4497 if rp == nil { 4498 aggregator, emitter := itr.create() 4499 rp = &integerReduceUnsignedPoint{ 4500 Name: curr.Name, 4501 Tags: tags, 4502 Aggregator: aggregator, 4503 Emitter: emitter, 4504 } 4505 itr.m[id] = rp 4506 } 4507 rp.Aggregator.AggregateInteger(curr) 4508 4509 // Attempt to emit points from the aggregator. 4510 points := rp.Emitter.Emit() 4511 if len(points) == 0 { 4512 continue 4513 } 4514 4515 for i := range points { 4516 points[i].Name = rp.Name 4517 points[i].Tags = rp.Tags 4518 } 4519 return points, nil 4520 } 4521 } 4522 4523 // integerReduceStringIterator executes a reducer for every interval and buffers the result. 4524 type integerReduceStringIterator struct { 4525 input *bufIntegerIterator 4526 create func() (IntegerPointAggregator, StringPointEmitter) 4527 dims []string 4528 opt IteratorOptions 4529 points []StringPoint 4530 keepTags bool 4531 } 4532 4533 func newIntegerReduceStringIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, StringPointEmitter)) *integerReduceStringIterator { 4534 return &integerReduceStringIterator{ 4535 input: newBufIntegerIterator(input), 4536 create: createFn, 4537 dims: opt.GetDimensions(), 4538 opt: opt, 4539 } 4540 } 4541 4542 // Stats returns stats from the input iterator. 4543 func (itr *integerReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() } 4544 4545 // Close closes the iterator and all child iterators. 4546 func (itr *integerReduceStringIterator) Close() error { return itr.input.Close() } 4547 4548 // Next returns the minimum value for the next available interval. 4549 func (itr *integerReduceStringIterator) Next() (*StringPoint, error) { 4550 // Calculate next window if we have no more points. 4551 if len(itr.points) == 0 { 4552 var err error 4553 itr.points, err = itr.reduce() 4554 if len(itr.points) == 0 { 4555 return nil, err 4556 } 4557 } 4558 4559 // Pop next point off the stack. 4560 p := &itr.points[len(itr.points)-1] 4561 itr.points = itr.points[:len(itr.points)-1] 4562 return p, nil 4563 } 4564 4565 // integerReduceStringPoint stores the reduced data for a name/tag combination. 4566 type integerReduceStringPoint struct { 4567 Name string 4568 Tags Tags 4569 Aggregator IntegerPointAggregator 4570 Emitter StringPointEmitter 4571 } 4572 4573 // reduce executes fn once for every point in the next window. 4574 // The previous value for the dimension is passed to fn. 4575 func (itr *integerReduceStringIterator) reduce() ([]StringPoint, error) { 4576 // Calculate next window. 4577 var ( 4578 startTime, endTime int64 4579 window struct { 4580 name string 4581 tags string 4582 } 4583 ) 4584 for { 4585 p, err := itr.input.Next() 4586 if err != nil || p == nil { 4587 return nil, err 4588 } else if p.Nil { 4589 continue 4590 } 4591 4592 // Unread the point so it can be processed. 4593 itr.input.unread(p) 4594 startTime, endTime = itr.opt.Window(p.Time) 4595 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 4596 break 4597 } 4598 4599 // Create points by tags. 4600 m := make(map[string]*integerReduceStringPoint) 4601 for { 4602 // Read next point. 4603 curr, err := itr.input.NextInWindow(startTime, endTime) 4604 if err != nil { 4605 return nil, err 4606 } else if curr == nil { 4607 break 4608 } else if curr.Nil { 4609 continue 4610 } else if curr.Name != window.name { 4611 itr.input.unread(curr) 4612 break 4613 } 4614 4615 // Ensure this point is within the same final window. 4616 if curr.Name != window.name { 4617 itr.input.unread(curr) 4618 break 4619 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 4620 itr.input.unread(curr) 4621 break 4622 } 4623 4624 // Retrieve the tags on this point for this level of the query. 4625 // This may be different than the bucket dimensions. 4626 tags := curr.Tags.Subset(itr.dims) 4627 id := tags.ID() 4628 4629 // Retrieve the aggregator for this name/tag combination or create one. 4630 rp := m[id] 4631 if rp == nil { 4632 aggregator, emitter := itr.create() 4633 rp = &integerReduceStringPoint{ 4634 Name: curr.Name, 4635 Tags: tags, 4636 Aggregator: aggregator, 4637 Emitter: emitter, 4638 } 4639 m[id] = rp 4640 } 4641 rp.Aggregator.AggregateInteger(curr) 4642 } 4643 4644 keys := make([]string, 0, len(m)) 4645 for k := range m { 4646 keys = append(keys, k) 4647 } 4648 4649 // Reverse sort points by name & tag. 4650 // This ensures a consistent order of output. 4651 if len(keys) > 0 { 4652 var sorted sort.Interface = sort.StringSlice(keys) 4653 if itr.opt.Ascending { 4654 sorted = sort.Reverse(sorted) 4655 } 4656 sort.Sort(sorted) 4657 } 4658 4659 // Assume the points are already sorted until proven otherwise. 4660 sortedByTime := true 4661 // Emit the points for each name & tag combination. 4662 a := make([]StringPoint, 0, len(m)) 4663 for _, k := range keys { 4664 rp := m[k] 4665 points := rp.Emitter.Emit() 4666 for i := len(points) - 1; i >= 0; i-- { 4667 points[i].Name = rp.Name 4668 if !itr.keepTags { 4669 points[i].Tags = rp.Tags 4670 } 4671 // Set the points time to the interval time if the reducer didn't provide one. 4672 if points[i].Time == ZeroTime { 4673 points[i].Time = startTime 4674 } else { 4675 sortedByTime = false 4676 } 4677 a = append(a, points[i]) 4678 } 4679 } 4680 // Points may be out of order. Perform a stable sort by time if requested. 4681 if !sortedByTime && itr.opt.Ordered { 4682 var sorted sort.Interface = stringPointsByTime(a) 4683 if itr.opt.Ascending { 4684 sorted = sort.Reverse(sorted) 4685 } 4686 sort.Stable(sorted) 4687 } 4688 return a, nil 4689 } 4690 4691 // integerStreamStringIterator streams inputs into the iterator and emits points gradually. 4692 type integerStreamStringIterator struct { 4693 input *bufIntegerIterator 4694 create func() (IntegerPointAggregator, StringPointEmitter) 4695 dims []string 4696 opt IteratorOptions 4697 m map[string]*integerReduceStringPoint 4698 points []StringPoint 4699 } 4700 4701 // newIntegerStreamStringIterator returns a new instance of integerStreamStringIterator. 4702 func newIntegerStreamStringIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, StringPointEmitter), opt IteratorOptions) *integerStreamStringIterator { 4703 return &integerStreamStringIterator{ 4704 input: newBufIntegerIterator(input), 4705 create: createFn, 4706 dims: opt.GetDimensions(), 4707 opt: opt, 4708 m: make(map[string]*integerReduceStringPoint), 4709 } 4710 } 4711 4712 // Stats returns stats from the input iterator. 4713 func (itr *integerStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() } 4714 4715 // Close closes the iterator and all child iterators. 4716 func (itr *integerStreamStringIterator) Close() error { return itr.input.Close() } 4717 4718 // Next returns the next value for the stream iterator. 4719 func (itr *integerStreamStringIterator) Next() (*StringPoint, error) { 4720 // Calculate next window if we have no more points. 4721 if len(itr.points) == 0 { 4722 var err error 4723 itr.points, err = itr.reduce() 4724 if len(itr.points) == 0 { 4725 return nil, err 4726 } 4727 } 4728 4729 // Pop next point off the stack. 4730 p := &itr.points[len(itr.points)-1] 4731 itr.points = itr.points[:len(itr.points)-1] 4732 return p, nil 4733 } 4734 4735 // reduce creates and manages aggregators for every point from the input. 4736 // After aggregating a point, it always tries to emit a value using the emitter. 4737 func (itr *integerStreamStringIterator) reduce() ([]StringPoint, error) { 4738 // We have already read all of the input points. 4739 if itr.m == nil { 4740 return nil, nil 4741 } 4742 4743 for { 4744 // Read next point. 4745 curr, err := itr.input.Next() 4746 if err != nil { 4747 return nil, err 4748 } else if curr == nil { 4749 // Close all of the aggregators to flush any remaining points to emit. 4750 var points []StringPoint 4751 for _, rp := range itr.m { 4752 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 4753 if err := aggregator.Close(); err != nil { 4754 return nil, err 4755 } 4756 4757 pts := rp.Emitter.Emit() 4758 if len(pts) == 0 { 4759 continue 4760 } 4761 4762 for i := range pts { 4763 pts[i].Name = rp.Name 4764 pts[i].Tags = rp.Tags 4765 } 4766 points = append(points, pts...) 4767 } 4768 } 4769 4770 // Eliminate the aggregators and emitters. 4771 itr.m = nil 4772 return points, nil 4773 } else if curr.Nil { 4774 continue 4775 } 4776 tags := curr.Tags.Subset(itr.dims) 4777 4778 id := curr.Name 4779 if len(tags.m) > 0 { 4780 id += "\x00" + tags.ID() 4781 } 4782 4783 // Retrieve the aggregator for this name/tag combination or create one. 4784 rp := itr.m[id] 4785 if rp == nil { 4786 aggregator, emitter := itr.create() 4787 rp = &integerReduceStringPoint{ 4788 Name: curr.Name, 4789 Tags: tags, 4790 Aggregator: aggregator, 4791 Emitter: emitter, 4792 } 4793 itr.m[id] = rp 4794 } 4795 rp.Aggregator.AggregateInteger(curr) 4796 4797 // Attempt to emit points from the aggregator. 4798 points := rp.Emitter.Emit() 4799 if len(points) == 0 { 4800 continue 4801 } 4802 4803 for i := range points { 4804 points[i].Name = rp.Name 4805 points[i].Tags = rp.Tags 4806 } 4807 return points, nil 4808 } 4809 } 4810 4811 // integerReduceBooleanIterator executes a reducer for every interval and buffers the result. 4812 type integerReduceBooleanIterator struct { 4813 input *bufIntegerIterator 4814 create func() (IntegerPointAggregator, BooleanPointEmitter) 4815 dims []string 4816 opt IteratorOptions 4817 points []BooleanPoint 4818 keepTags bool 4819 } 4820 4821 func newIntegerReduceBooleanIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, BooleanPointEmitter)) *integerReduceBooleanIterator { 4822 return &integerReduceBooleanIterator{ 4823 input: newBufIntegerIterator(input), 4824 create: createFn, 4825 dims: opt.GetDimensions(), 4826 opt: opt, 4827 } 4828 } 4829 4830 // Stats returns stats from the input iterator. 4831 func (itr *integerReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() } 4832 4833 // Close closes the iterator and all child iterators. 4834 func (itr *integerReduceBooleanIterator) Close() error { return itr.input.Close() } 4835 4836 // Next returns the minimum value for the next available interval. 4837 func (itr *integerReduceBooleanIterator) Next() (*BooleanPoint, error) { 4838 // Calculate next window if we have no more points. 4839 if len(itr.points) == 0 { 4840 var err error 4841 itr.points, err = itr.reduce() 4842 if len(itr.points) == 0 { 4843 return nil, err 4844 } 4845 } 4846 4847 // Pop next point off the stack. 4848 p := &itr.points[len(itr.points)-1] 4849 itr.points = itr.points[:len(itr.points)-1] 4850 return p, nil 4851 } 4852 4853 // integerReduceBooleanPoint stores the reduced data for a name/tag combination. 4854 type integerReduceBooleanPoint struct { 4855 Name string 4856 Tags Tags 4857 Aggregator IntegerPointAggregator 4858 Emitter BooleanPointEmitter 4859 } 4860 4861 // reduce executes fn once for every point in the next window. 4862 // The previous value for the dimension is passed to fn. 4863 func (itr *integerReduceBooleanIterator) reduce() ([]BooleanPoint, error) { 4864 // Calculate next window. 4865 var ( 4866 startTime, endTime int64 4867 window struct { 4868 name string 4869 tags string 4870 } 4871 ) 4872 for { 4873 p, err := itr.input.Next() 4874 if err != nil || p == nil { 4875 return nil, err 4876 } else if p.Nil { 4877 continue 4878 } 4879 4880 // Unread the point so it can be processed. 4881 itr.input.unread(p) 4882 startTime, endTime = itr.opt.Window(p.Time) 4883 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 4884 break 4885 } 4886 4887 // Create points by tags. 4888 m := make(map[string]*integerReduceBooleanPoint) 4889 for { 4890 // Read next point. 4891 curr, err := itr.input.NextInWindow(startTime, endTime) 4892 if err != nil { 4893 return nil, err 4894 } else if curr == nil { 4895 break 4896 } else if curr.Nil { 4897 continue 4898 } else if curr.Name != window.name { 4899 itr.input.unread(curr) 4900 break 4901 } 4902 4903 // Ensure this point is within the same final window. 4904 if curr.Name != window.name { 4905 itr.input.unread(curr) 4906 break 4907 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 4908 itr.input.unread(curr) 4909 break 4910 } 4911 4912 // Retrieve the tags on this point for this level of the query. 4913 // This may be different than the bucket dimensions. 4914 tags := curr.Tags.Subset(itr.dims) 4915 id := tags.ID() 4916 4917 // Retrieve the aggregator for this name/tag combination or create one. 4918 rp := m[id] 4919 if rp == nil { 4920 aggregator, emitter := itr.create() 4921 rp = &integerReduceBooleanPoint{ 4922 Name: curr.Name, 4923 Tags: tags, 4924 Aggregator: aggregator, 4925 Emitter: emitter, 4926 } 4927 m[id] = rp 4928 } 4929 rp.Aggregator.AggregateInteger(curr) 4930 } 4931 4932 keys := make([]string, 0, len(m)) 4933 for k := range m { 4934 keys = append(keys, k) 4935 } 4936 4937 // Reverse sort points by name & tag. 4938 // This ensures a consistent order of output. 4939 if len(keys) > 0 { 4940 var sorted sort.Interface = sort.StringSlice(keys) 4941 if itr.opt.Ascending { 4942 sorted = sort.Reverse(sorted) 4943 } 4944 sort.Sort(sorted) 4945 } 4946 4947 // Assume the points are already sorted until proven otherwise. 4948 sortedByTime := true 4949 // Emit the points for each name & tag combination. 4950 a := make([]BooleanPoint, 0, len(m)) 4951 for _, k := range keys { 4952 rp := m[k] 4953 points := rp.Emitter.Emit() 4954 for i := len(points) - 1; i >= 0; i-- { 4955 points[i].Name = rp.Name 4956 if !itr.keepTags { 4957 points[i].Tags = rp.Tags 4958 } 4959 // Set the points time to the interval time if the reducer didn't provide one. 4960 if points[i].Time == ZeroTime { 4961 points[i].Time = startTime 4962 } else { 4963 sortedByTime = false 4964 } 4965 a = append(a, points[i]) 4966 } 4967 } 4968 // Points may be out of order. Perform a stable sort by time if requested. 4969 if !sortedByTime && itr.opt.Ordered { 4970 var sorted sort.Interface = booleanPointsByTime(a) 4971 if itr.opt.Ascending { 4972 sorted = sort.Reverse(sorted) 4973 } 4974 sort.Stable(sorted) 4975 } 4976 return a, nil 4977 } 4978 4979 // integerStreamBooleanIterator streams inputs into the iterator and emits points gradually. 4980 type integerStreamBooleanIterator struct { 4981 input *bufIntegerIterator 4982 create func() (IntegerPointAggregator, BooleanPointEmitter) 4983 dims []string 4984 opt IteratorOptions 4985 m map[string]*integerReduceBooleanPoint 4986 points []BooleanPoint 4987 } 4988 4989 // newIntegerStreamBooleanIterator returns a new instance of integerStreamBooleanIterator. 4990 func newIntegerStreamBooleanIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, BooleanPointEmitter), opt IteratorOptions) *integerStreamBooleanIterator { 4991 return &integerStreamBooleanIterator{ 4992 input: newBufIntegerIterator(input), 4993 create: createFn, 4994 dims: opt.GetDimensions(), 4995 opt: opt, 4996 m: make(map[string]*integerReduceBooleanPoint), 4997 } 4998 } 4999 5000 // Stats returns stats from the input iterator. 5001 func (itr *integerStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() } 5002 5003 // Close closes the iterator and all child iterators. 5004 func (itr *integerStreamBooleanIterator) Close() error { return itr.input.Close() } 5005 5006 // Next returns the next value for the stream iterator. 5007 func (itr *integerStreamBooleanIterator) Next() (*BooleanPoint, error) { 5008 // Calculate next window if we have no more points. 5009 if len(itr.points) == 0 { 5010 var err error 5011 itr.points, err = itr.reduce() 5012 if len(itr.points) == 0 { 5013 return nil, err 5014 } 5015 } 5016 5017 // Pop next point off the stack. 5018 p := &itr.points[len(itr.points)-1] 5019 itr.points = itr.points[:len(itr.points)-1] 5020 return p, nil 5021 } 5022 5023 // reduce creates and manages aggregators for every point from the input. 5024 // After aggregating a point, it always tries to emit a value using the emitter. 5025 func (itr *integerStreamBooleanIterator) reduce() ([]BooleanPoint, error) { 5026 // We have already read all of the input points. 5027 if itr.m == nil { 5028 return nil, nil 5029 } 5030 5031 for { 5032 // Read next point. 5033 curr, err := itr.input.Next() 5034 if err != nil { 5035 return nil, err 5036 } else if curr == nil { 5037 // Close all of the aggregators to flush any remaining points to emit. 5038 var points []BooleanPoint 5039 for _, rp := range itr.m { 5040 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 5041 if err := aggregator.Close(); err != nil { 5042 return nil, err 5043 } 5044 5045 pts := rp.Emitter.Emit() 5046 if len(pts) == 0 { 5047 continue 5048 } 5049 5050 for i := range pts { 5051 pts[i].Name = rp.Name 5052 pts[i].Tags = rp.Tags 5053 } 5054 points = append(points, pts...) 5055 } 5056 } 5057 5058 // Eliminate the aggregators and emitters. 5059 itr.m = nil 5060 return points, nil 5061 } else if curr.Nil { 5062 continue 5063 } 5064 tags := curr.Tags.Subset(itr.dims) 5065 5066 id := curr.Name 5067 if len(tags.m) > 0 { 5068 id += "\x00" + tags.ID() 5069 } 5070 5071 // Retrieve the aggregator for this name/tag combination or create one. 5072 rp := itr.m[id] 5073 if rp == nil { 5074 aggregator, emitter := itr.create() 5075 rp = &integerReduceBooleanPoint{ 5076 Name: curr.Name, 5077 Tags: tags, 5078 Aggregator: aggregator, 5079 Emitter: emitter, 5080 } 5081 itr.m[id] = rp 5082 } 5083 rp.Aggregator.AggregateInteger(curr) 5084 5085 // Attempt to emit points from the aggregator. 5086 points := rp.Emitter.Emit() 5087 if len(points) == 0 { 5088 continue 5089 } 5090 5091 for i := range points { 5092 points[i].Name = rp.Name 5093 points[i].Tags = rp.Tags 5094 } 5095 return points, nil 5096 } 5097 } 5098 5099 // integerDedupeIterator only outputs unique points. 5100 // This differs from the DistinctIterator in that it compares all aux fields too. 5101 // This iterator is relatively inefficient and should only be used on small 5102 // datasets such as meta query results. 5103 type integerDedupeIterator struct { 5104 input IntegerIterator 5105 m map[string]struct{} // lookup of points already sent 5106 } 5107 5108 type integerIteratorMapper struct { 5109 cur Cursor 5110 row Row 5111 driver IteratorMap // which iterator to use for the primary value, can be nil 5112 fields []IteratorMap // which iterator to use for an aux field 5113 point IntegerPoint 5114 } 5115 5116 func newIntegerIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *integerIteratorMapper { 5117 return &integerIteratorMapper{ 5118 cur: cur, 5119 driver: driver, 5120 fields: fields, 5121 point: IntegerPoint{ 5122 Aux: make([]interface{}, len(fields)), 5123 }, 5124 } 5125 } 5126 5127 func (itr *integerIteratorMapper) Next() (*IntegerPoint, error) { 5128 if !itr.cur.Scan(&itr.row) { 5129 if err := itr.cur.Err(); err != nil { 5130 return nil, err 5131 } 5132 return nil, nil 5133 } 5134 5135 itr.point.Time = itr.row.Time 5136 itr.point.Name = itr.row.Series.Name 5137 itr.point.Tags = itr.row.Series.Tags 5138 5139 if itr.driver != nil { 5140 if v := itr.driver.Value(&itr.row); v != nil { 5141 if v, ok := castToInteger(v); ok { 5142 itr.point.Value = v 5143 itr.point.Nil = false 5144 } else { 5145 itr.point.Value = 0 5146 itr.point.Nil = true 5147 } 5148 } else { 5149 itr.point.Value = 0 5150 itr.point.Nil = true 5151 } 5152 } 5153 for i, f := range itr.fields { 5154 itr.point.Aux[i] = f.Value(&itr.row) 5155 } 5156 return &itr.point, nil 5157 } 5158 5159 func (itr *integerIteratorMapper) Stats() IteratorStats { 5160 return itr.cur.Stats() 5161 } 5162 5163 func (itr *integerIteratorMapper) Close() error { 5164 return itr.cur.Close() 5165 } 5166 5167 type integerFilterIterator struct { 5168 input IntegerIterator 5169 cond influxql.Expr 5170 opt IteratorOptions 5171 m map[string]interface{} 5172 } 5173 5174 func newIntegerFilterIterator(input IntegerIterator, cond influxql.Expr, opt IteratorOptions) IntegerIterator { 5175 // Strip out time conditions from the WHERE clause. 5176 // TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct. 5177 n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node { 5178 switch n := n.(type) { 5179 case *influxql.BinaryExpr: 5180 if n.LHS.String() == "time" { 5181 return &influxql.BooleanLiteral{Val: true} 5182 } 5183 } 5184 return n 5185 }) 5186 5187 cond, _ = n.(influxql.Expr) 5188 if cond == nil { 5189 return input 5190 } else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val { 5191 return input 5192 } 5193 5194 return &integerFilterIterator{ 5195 input: input, 5196 cond: cond, 5197 opt: opt, 5198 m: make(map[string]interface{}), 5199 } 5200 } 5201 5202 func (itr *integerFilterIterator) Stats() IteratorStats { return itr.input.Stats() } 5203 func (itr *integerFilterIterator) Close() error { return itr.input.Close() } 5204 5205 func (itr *integerFilterIterator) Next() (*IntegerPoint, error) { 5206 for { 5207 p, err := itr.input.Next() 5208 if err != nil || p == nil { 5209 return nil, err 5210 } 5211 5212 for i, ref := range itr.opt.Aux { 5213 itr.m[ref.Val] = p.Aux[i] 5214 } 5215 for k, v := range p.Tags.KeyValues() { 5216 itr.m[k] = v 5217 } 5218 5219 if !influxql.EvalBool(itr.cond, itr.m) { 5220 continue 5221 } 5222 return p, nil 5223 } 5224 } 5225 5226 type integerTagSubsetIterator struct { 5227 input IntegerIterator 5228 point IntegerPoint 5229 lastTags Tags 5230 dimensions []string 5231 } 5232 5233 func newIntegerTagSubsetIterator(input IntegerIterator, opt IteratorOptions) *integerTagSubsetIterator { 5234 return &integerTagSubsetIterator{ 5235 input: input, 5236 dimensions: opt.GetDimensions(), 5237 } 5238 } 5239 5240 func (itr *integerTagSubsetIterator) Next() (*IntegerPoint, error) { 5241 p, err := itr.input.Next() 5242 if err != nil { 5243 return nil, err 5244 } else if p == nil { 5245 return nil, nil 5246 } 5247 5248 itr.point.Name = p.Name 5249 if !p.Tags.Equal(itr.lastTags) { 5250 itr.point.Tags = p.Tags.Subset(itr.dimensions) 5251 itr.lastTags = p.Tags 5252 } 5253 itr.point.Time = p.Time 5254 itr.point.Value = p.Value 5255 itr.point.Aux = p.Aux 5256 itr.point.Aggregated = p.Aggregated 5257 itr.point.Nil = p.Nil 5258 return &itr.point, nil 5259 } 5260 5261 func (itr *integerTagSubsetIterator) Stats() IteratorStats { 5262 return itr.input.Stats() 5263 } 5264 5265 func (itr *integerTagSubsetIterator) Close() error { 5266 return itr.input.Close() 5267 } 5268 5269 // newIntegerDedupeIterator returns a new instance of integerDedupeIterator. 5270 func newIntegerDedupeIterator(input IntegerIterator) *integerDedupeIterator { 5271 return &integerDedupeIterator{ 5272 input: input, 5273 m: make(map[string]struct{}), 5274 } 5275 } 5276 5277 // Stats returns stats from the input iterator. 5278 func (itr *integerDedupeIterator) Stats() IteratorStats { return itr.input.Stats() } 5279 5280 // Close closes the iterator and all child iterators. 5281 func (itr *integerDedupeIterator) Close() error { return itr.input.Close() } 5282 5283 // Next returns the next unique point from the input iterator. 5284 func (itr *integerDedupeIterator) Next() (*IntegerPoint, error) { 5285 for { 5286 // Read next point. 5287 p, err := itr.input.Next() 5288 if p == nil || err != nil { 5289 return nil, err 5290 } 5291 5292 // Serialize to bytes to store in lookup. 5293 buf, err := proto.Marshal(encodeIntegerPoint(p)) 5294 if err != nil { 5295 return nil, err 5296 } 5297 5298 // If the point has already been output then move to the next point. 5299 if _, ok := itr.m[string(buf)]; ok { 5300 continue 5301 } 5302 5303 // Otherwise mark it as emitted and return point. 5304 itr.m[string(buf)] = struct{}{} 5305 return p, nil 5306 } 5307 } 5308 5309 // integerReaderIterator represents an iterator that streams from a reader. 5310 type integerReaderIterator struct { 5311 r io.Reader 5312 dec *IntegerPointDecoder 5313 } 5314 5315 // newIntegerReaderIterator returns a new instance of integerReaderIterator. 5316 func newIntegerReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *integerReaderIterator { 5317 dec := NewIntegerPointDecoder(ctx, r) 5318 dec.stats = stats 5319 5320 return &integerReaderIterator{ 5321 r: r, 5322 dec: dec, 5323 } 5324 } 5325 5326 // Stats returns stats about points processed. 5327 func (itr *integerReaderIterator) Stats() IteratorStats { return itr.dec.stats } 5328 5329 // Close closes the underlying reader, if applicable. 5330 func (itr *integerReaderIterator) Close() error { 5331 if r, ok := itr.r.(io.ReadCloser); ok { 5332 return r.Close() 5333 } 5334 return nil 5335 } 5336 5337 // Next returns the next point from the iterator. 5338 func (itr *integerReaderIterator) Next() (*IntegerPoint, error) { 5339 // OPTIMIZE(benbjohnson): Reuse point on iterator. 5340 5341 // Unmarshal next point. 5342 p := &IntegerPoint{} 5343 if err := itr.dec.DecodeIntegerPoint(p); err == io.EOF { 5344 return nil, nil 5345 } else if err != nil { 5346 return nil, err 5347 } 5348 return p, nil 5349 } 5350 5351 // UnsignedIterator represents a stream of unsigned points. 5352 type UnsignedIterator interface { 5353 Iterator 5354 Next() (*UnsignedPoint, error) 5355 } 5356 5357 // newUnsignedIterators converts a slice of Iterator to a slice of UnsignedIterator. 5358 // Drop and closes any iterator in itrs that is not a UnsignedIterator and cannot 5359 // be cast to a UnsignedIterator. 5360 func newUnsignedIterators(itrs []Iterator) []UnsignedIterator { 5361 a := make([]UnsignedIterator, 0, len(itrs)) 5362 for _, itr := range itrs { 5363 switch itr := itr.(type) { 5364 case UnsignedIterator: 5365 a = append(a, itr) 5366 default: 5367 itr.Close() 5368 } 5369 } 5370 return a 5371 } 5372 5373 // bufUnsignedIterator represents a buffered UnsignedIterator. 5374 type bufUnsignedIterator struct { 5375 itr UnsignedIterator 5376 buf *UnsignedPoint 5377 } 5378 5379 // newBufUnsignedIterator returns a buffered UnsignedIterator. 5380 func newBufUnsignedIterator(itr UnsignedIterator) *bufUnsignedIterator { 5381 return &bufUnsignedIterator{itr: itr} 5382 } 5383 5384 // Stats returns statistics from the input iterator. 5385 func (itr *bufUnsignedIterator) Stats() IteratorStats { return itr.itr.Stats() } 5386 5387 // Close closes the underlying iterator. 5388 func (itr *bufUnsignedIterator) Close() error { return itr.itr.Close() } 5389 5390 // peek returns the next point without removing it from the iterator. 5391 func (itr *bufUnsignedIterator) peek() (*UnsignedPoint, error) { 5392 p, err := itr.Next() 5393 if err != nil { 5394 return nil, err 5395 } 5396 itr.unread(p) 5397 return p, nil 5398 } 5399 5400 // peekTime returns the time of the next point. 5401 // Returns zero time if no more points available. 5402 func (itr *bufUnsignedIterator) peekTime() (int64, error) { 5403 p, err := itr.peek() 5404 if p == nil || err != nil { 5405 return ZeroTime, err 5406 } 5407 return p.Time, nil 5408 } 5409 5410 // Next returns the current buffer, if exists, or calls the underlying iterator. 5411 func (itr *bufUnsignedIterator) Next() (*UnsignedPoint, error) { 5412 buf := itr.buf 5413 if buf != nil { 5414 itr.buf = nil 5415 return buf, nil 5416 } 5417 return itr.itr.Next() 5418 } 5419 5420 // NextInWindow returns the next value if it is between [startTime, endTime). 5421 // If the next value is outside the range then it is moved to the buffer. 5422 func (itr *bufUnsignedIterator) NextInWindow(startTime, endTime int64) (*UnsignedPoint, error) { 5423 v, err := itr.Next() 5424 if v == nil || err != nil { 5425 return nil, err 5426 } else if t := v.Time; t >= endTime || t < startTime { 5427 itr.unread(v) 5428 return nil, nil 5429 } 5430 return v, nil 5431 } 5432 5433 // unread sets v to the buffer. It is read on the next call to Next(). 5434 func (itr *bufUnsignedIterator) unread(v *UnsignedPoint) { itr.buf = v } 5435 5436 // unsignedMergeIterator represents an iterator that combines multiple unsigned iterators. 5437 type unsignedMergeIterator struct { 5438 inputs []UnsignedIterator 5439 heap *unsignedMergeHeap 5440 init bool 5441 5442 closed bool 5443 mu sync.RWMutex 5444 5445 // Current iterator and window. 5446 curr *unsignedMergeHeapItem 5447 window struct { 5448 name string 5449 tags string 5450 startTime int64 5451 endTime int64 5452 } 5453 } 5454 5455 // newUnsignedMergeIterator returns a new instance of unsignedMergeIterator. 5456 func newUnsignedMergeIterator(inputs []UnsignedIterator, opt IteratorOptions) *unsignedMergeIterator { 5457 itr := &unsignedMergeIterator{ 5458 inputs: inputs, 5459 heap: &unsignedMergeHeap{ 5460 items: make([]*unsignedMergeHeapItem, 0, len(inputs)), 5461 opt: opt, 5462 }, 5463 } 5464 5465 // Initialize heap items. 5466 for _, input := range inputs { 5467 // Wrap in buffer, ignore any inputs without anymore points. 5468 bufInput := newBufUnsignedIterator(input) 5469 5470 // Append to the heap. 5471 itr.heap.items = append(itr.heap.items, &unsignedMergeHeapItem{itr: bufInput}) 5472 } 5473 5474 return itr 5475 } 5476 5477 // Stats returns an aggregation of stats from the underlying iterators. 5478 func (itr *unsignedMergeIterator) Stats() IteratorStats { 5479 var stats IteratorStats 5480 for _, input := range itr.inputs { 5481 stats.Add(input.Stats()) 5482 } 5483 return stats 5484 } 5485 5486 // Close closes the underlying iterators. 5487 func (itr *unsignedMergeIterator) Close() error { 5488 itr.mu.Lock() 5489 defer itr.mu.Unlock() 5490 5491 for _, input := range itr.inputs { 5492 input.Close() 5493 } 5494 itr.curr = nil 5495 itr.inputs = nil 5496 itr.heap.items = nil 5497 itr.closed = true 5498 return nil 5499 } 5500 5501 // Next returns the next point from the iterator. 5502 func (itr *unsignedMergeIterator) Next() (*UnsignedPoint, error) { 5503 itr.mu.RLock() 5504 defer itr.mu.RUnlock() 5505 if itr.closed { 5506 return nil, nil 5507 } 5508 5509 // Initialize the heap. This needs to be done lazily on the first call to this iterator 5510 // so that iterator initialization done through the Select() call returns quickly. 5511 // Queries can only be interrupted after the Select() call completes so any operations 5512 // done during iterator creation cannot be interrupted, which is why we do it here 5513 // instead so an interrupt can happen while initializing the heap. 5514 if !itr.init { 5515 items := itr.heap.items 5516 itr.heap.items = make([]*unsignedMergeHeapItem, 0, len(items)) 5517 for _, item := range items { 5518 if p, err := item.itr.peek(); err != nil { 5519 return nil, err 5520 } else if p == nil { 5521 continue 5522 } 5523 itr.heap.items = append(itr.heap.items, item) 5524 } 5525 heap.Init(itr.heap) 5526 itr.init = true 5527 } 5528 5529 for { 5530 // Retrieve the next iterator if we don't have one. 5531 if itr.curr == nil { 5532 if len(itr.heap.items) == 0 { 5533 return nil, nil 5534 } 5535 itr.curr = heap.Pop(itr.heap).(*unsignedMergeHeapItem) 5536 5537 // Read point and set current window. 5538 p, err := itr.curr.itr.Next() 5539 if err != nil { 5540 return nil, err 5541 } 5542 tags := p.Tags.Subset(itr.heap.opt.Dimensions) 5543 itr.window.name, itr.window.tags = p.Name, tags.ID() 5544 itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time) 5545 return p, nil 5546 } 5547 5548 // Read the next point from the current iterator. 5549 p, err := itr.curr.itr.Next() 5550 if err != nil { 5551 return nil, err 5552 } 5553 5554 // If there are no more points then remove iterator from heap and find next. 5555 if p == nil { 5556 itr.curr = nil 5557 continue 5558 } 5559 5560 // Check if the point is inside of our current window. 5561 inWindow := true 5562 if window := itr.window; window.name != p.Name { 5563 inWindow = false 5564 } else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() { 5565 inWindow = false 5566 } else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime { 5567 inWindow = false 5568 } else if !opt.Ascending && p.Time < window.startTime { 5569 inWindow = false 5570 } 5571 5572 // If it's outside our window then push iterator back on the heap and find new iterator. 5573 if !inWindow { 5574 itr.curr.itr.unread(p) 5575 heap.Push(itr.heap, itr.curr) 5576 itr.curr = nil 5577 continue 5578 } 5579 5580 return p, nil 5581 } 5582 } 5583 5584 // unsignedMergeHeap represents a heap of unsignedMergeHeapItems. 5585 // Items are sorted by their next window and then by name/tags. 5586 type unsignedMergeHeap struct { 5587 opt IteratorOptions 5588 items []*unsignedMergeHeapItem 5589 } 5590 5591 func (h *unsignedMergeHeap) Len() int { return len(h.items) } 5592 func (h *unsignedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] } 5593 func (h *unsignedMergeHeap) Less(i, j int) bool { 5594 x, err := h.items[i].itr.peek() 5595 if err != nil { 5596 return true 5597 } 5598 y, err := h.items[j].itr.peek() 5599 if err != nil { 5600 return false 5601 } 5602 5603 if h.opt.Ascending { 5604 if x.Name != y.Name { 5605 return x.Name < y.Name 5606 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() { 5607 return xTags.ID() < yTags.ID() 5608 } 5609 } else { 5610 if x.Name != y.Name { 5611 return x.Name > y.Name 5612 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() { 5613 return xTags.ID() > yTags.ID() 5614 } 5615 } 5616 5617 xt, _ := h.opt.Window(x.Time) 5618 yt, _ := h.opt.Window(y.Time) 5619 5620 if h.opt.Ascending { 5621 return xt < yt 5622 } 5623 return xt > yt 5624 } 5625 5626 func (h *unsignedMergeHeap) Push(x interface{}) { 5627 h.items = append(h.items, x.(*unsignedMergeHeapItem)) 5628 } 5629 5630 func (h *unsignedMergeHeap) Pop() interface{} { 5631 old := h.items 5632 n := len(old) 5633 item := old[n-1] 5634 h.items = old[0 : n-1] 5635 return item 5636 } 5637 5638 type unsignedMergeHeapItem struct { 5639 itr *bufUnsignedIterator 5640 } 5641 5642 // unsignedSortedMergeIterator is an iterator that sorts and merges multiple iterators into one. 5643 type unsignedSortedMergeIterator struct { 5644 inputs []UnsignedIterator 5645 heap *unsignedSortedMergeHeap 5646 init bool 5647 } 5648 5649 // newUnsignedSortedMergeIterator returns an instance of unsignedSortedMergeIterator. 5650 func newUnsignedSortedMergeIterator(inputs []UnsignedIterator, opt IteratorOptions) Iterator { 5651 itr := &unsignedSortedMergeIterator{ 5652 inputs: inputs, 5653 heap: &unsignedSortedMergeHeap{ 5654 items: make([]*unsignedSortedMergeHeapItem, 0, len(inputs)), 5655 opt: opt, 5656 }, 5657 } 5658 5659 // Initialize heap items. 5660 for _, input := range inputs { 5661 // Append to the heap. 5662 itr.heap.items = append(itr.heap.items, &unsignedSortedMergeHeapItem{itr: input}) 5663 } 5664 5665 return itr 5666 } 5667 5668 // Stats returns an aggregation of stats from the underlying iterators. 5669 func (itr *unsignedSortedMergeIterator) Stats() IteratorStats { 5670 var stats IteratorStats 5671 for _, input := range itr.inputs { 5672 stats.Add(input.Stats()) 5673 } 5674 return stats 5675 } 5676 5677 // Close closes the underlying iterators. 5678 func (itr *unsignedSortedMergeIterator) Close() error { 5679 for _, input := range itr.inputs { 5680 input.Close() 5681 } 5682 return nil 5683 } 5684 5685 // Next returns the next points from the iterator. 5686 func (itr *unsignedSortedMergeIterator) Next() (*UnsignedPoint, error) { return itr.pop() } 5687 5688 // pop returns the next point from the heap. 5689 // Reads the next point from item's cursor and puts it back on the heap. 5690 func (itr *unsignedSortedMergeIterator) pop() (*UnsignedPoint, error) { 5691 // Initialize the heap. See the MergeIterator to see why this has to be done lazily. 5692 if !itr.init { 5693 items := itr.heap.items 5694 itr.heap.items = make([]*unsignedSortedMergeHeapItem, 0, len(items)) 5695 for _, item := range items { 5696 var err error 5697 if item.point, err = item.itr.Next(); err != nil { 5698 return nil, err 5699 } else if item.point == nil { 5700 continue 5701 } 5702 itr.heap.items = append(itr.heap.items, item) 5703 } 5704 heap.Init(itr.heap) 5705 itr.init = true 5706 } 5707 5708 if len(itr.heap.items) == 0 { 5709 return nil, nil 5710 } 5711 5712 // Read the next item from the heap. 5713 item := heap.Pop(itr.heap).(*unsignedSortedMergeHeapItem) 5714 if item.err != nil { 5715 return nil, item.err 5716 } else if item.point == nil { 5717 return nil, nil 5718 } 5719 5720 // Copy the point for return. 5721 p := item.point.Clone() 5722 5723 // Read the next item from the cursor. Push back to heap if one exists. 5724 if item.point, item.err = item.itr.Next(); item.point != nil { 5725 heap.Push(itr.heap, item) 5726 } 5727 5728 return p, nil 5729 } 5730 5731 // unsignedSortedMergeHeap represents a heap of unsignedSortedMergeHeapItems. 5732 // Items are sorted with the following priority: 5733 // - By their measurement name; 5734 // - By their tag keys/values; 5735 // - By time; or 5736 // - By their Aux field values. 5737 type unsignedSortedMergeHeap struct { 5738 opt IteratorOptions 5739 items []*unsignedSortedMergeHeapItem 5740 } 5741 5742 func (h *unsignedSortedMergeHeap) Len() int { return len(h.items) } 5743 func (h *unsignedSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] } 5744 func (h *unsignedSortedMergeHeap) Less(i, j int) bool { 5745 x, y := h.items[i].point, h.items[j].point 5746 5747 if h.opt.Ascending { 5748 if x.Name != y.Name { 5749 return x.Name < y.Name 5750 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) { 5751 return xTags.ID() < yTags.ID() 5752 } 5753 5754 if x.Time != y.Time { 5755 return x.Time < y.Time 5756 } 5757 5758 if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) { 5759 for i := 0; i < len(x.Aux); i++ { 5760 v1, ok1 := x.Aux[i].(string) 5761 v2, ok2 := y.Aux[i].(string) 5762 if !ok1 || !ok2 { 5763 // Unsupported types used in Aux fields. Maybe they 5764 // need to be added here? 5765 return false 5766 } else if v1 == v2 { 5767 continue 5768 } 5769 return v1 < v2 5770 } 5771 } 5772 return false // Times and/or Aux fields are equal. 5773 } 5774 5775 if x.Name != y.Name { 5776 return x.Name > y.Name 5777 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) { 5778 return xTags.ID() > yTags.ID() 5779 } 5780 5781 if x.Time != y.Time { 5782 return x.Time > y.Time 5783 } 5784 5785 if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) { 5786 for i := 0; i < len(x.Aux); i++ { 5787 v1, ok1 := x.Aux[i].(string) 5788 v2, ok2 := y.Aux[i].(string) 5789 if !ok1 || !ok2 { 5790 // Unsupported types used in Aux fields. Maybe they 5791 // need to be added here? 5792 return false 5793 } else if v1 == v2 { 5794 continue 5795 } 5796 return v1 > v2 5797 } 5798 } 5799 return false // Times and/or Aux fields are equal. 5800 } 5801 5802 func (h *unsignedSortedMergeHeap) Push(x interface{}) { 5803 h.items = append(h.items, x.(*unsignedSortedMergeHeapItem)) 5804 } 5805 5806 func (h *unsignedSortedMergeHeap) Pop() interface{} { 5807 old := h.items 5808 n := len(old) 5809 item := old[n-1] 5810 h.items = old[0 : n-1] 5811 return item 5812 } 5813 5814 type unsignedSortedMergeHeapItem struct { 5815 point *UnsignedPoint 5816 err error 5817 itr UnsignedIterator 5818 } 5819 5820 // unsignedIteratorScanner scans the results of a UnsignedIterator into a map. 5821 type unsignedIteratorScanner struct { 5822 input *bufUnsignedIterator 5823 err error 5824 keys []influxql.VarRef 5825 defaultValue interface{} 5826 } 5827 5828 // newUnsignedIteratorScanner creates a new IteratorScanner. 5829 func newUnsignedIteratorScanner(input UnsignedIterator, keys []influxql.VarRef, defaultValue interface{}) *unsignedIteratorScanner { 5830 return &unsignedIteratorScanner{ 5831 input: newBufUnsignedIterator(input), 5832 keys: keys, 5833 defaultValue: defaultValue, 5834 } 5835 } 5836 5837 func (s *unsignedIteratorScanner) Peek() (int64, string, Tags) { 5838 if s.err != nil { 5839 return ZeroTime, "", Tags{} 5840 } 5841 5842 p, err := s.input.peek() 5843 if err != nil { 5844 s.err = err 5845 return ZeroTime, "", Tags{} 5846 } else if p == nil { 5847 return ZeroTime, "", Tags{} 5848 } 5849 return p.Time, p.Name, p.Tags 5850 } 5851 5852 func (s *unsignedIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) { 5853 if s.err != nil { 5854 return 5855 } 5856 5857 p, err := s.input.Next() 5858 if err != nil { 5859 s.err = err 5860 return 5861 } else if p == nil { 5862 s.useDefaults(m) 5863 return 5864 } else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) { 5865 s.useDefaults(m) 5866 s.input.unread(p) 5867 return 5868 } 5869 5870 if k := s.keys[0]; k.Val != "" { 5871 if p.Nil { 5872 if s.defaultValue != SkipDefault { 5873 m[k.Val] = castToType(s.defaultValue, k.Type) 5874 } 5875 } else { 5876 m[k.Val] = p.Value 5877 } 5878 } 5879 for i, v := range p.Aux { 5880 k := s.keys[i+1] 5881 switch v.(type) { 5882 case float64, int64, uint64, string, bool: 5883 m[k.Val] = v 5884 default: 5885 // Insert the fill value if one was specified. 5886 if s.defaultValue != SkipDefault { 5887 m[k.Val] = castToType(s.defaultValue, k.Type) 5888 } 5889 } 5890 } 5891 } 5892 5893 func (s *unsignedIteratorScanner) useDefaults(m map[string]interface{}) { 5894 if s.defaultValue == SkipDefault { 5895 return 5896 } 5897 for _, k := range s.keys { 5898 if k.Val == "" { 5899 continue 5900 } 5901 m[k.Val] = castToType(s.defaultValue, k.Type) 5902 } 5903 } 5904 5905 func (s *unsignedIteratorScanner) Stats() IteratorStats { return s.input.Stats() } 5906 func (s *unsignedIteratorScanner) Err() error { return s.err } 5907 func (s *unsignedIteratorScanner) Close() error { return s.input.Close() } 5908 5909 // unsignedParallelIterator represents an iterator that pulls data in a separate goroutine. 5910 type unsignedParallelIterator struct { 5911 input UnsignedIterator 5912 ch chan unsignedPointError 5913 5914 once sync.Once 5915 closing chan struct{} 5916 wg sync.WaitGroup 5917 } 5918 5919 // newUnsignedParallelIterator returns a new instance of unsignedParallelIterator. 5920 func newUnsignedParallelIterator(input UnsignedIterator) *unsignedParallelIterator { 5921 itr := &unsignedParallelIterator{ 5922 input: input, 5923 ch: make(chan unsignedPointError, 256), 5924 closing: make(chan struct{}), 5925 } 5926 itr.wg.Add(1) 5927 go itr.monitor() 5928 return itr 5929 } 5930 5931 // Stats returns stats from the underlying iterator. 5932 func (itr *unsignedParallelIterator) Stats() IteratorStats { return itr.input.Stats() } 5933 5934 // Close closes the underlying iterators. 5935 func (itr *unsignedParallelIterator) Close() error { 5936 itr.once.Do(func() { close(itr.closing) }) 5937 itr.wg.Wait() 5938 return itr.input.Close() 5939 } 5940 5941 // Next returns the next point from the iterator. 5942 func (itr *unsignedParallelIterator) Next() (*UnsignedPoint, error) { 5943 v, ok := <-itr.ch 5944 if !ok { 5945 return nil, io.EOF 5946 } 5947 return v.point, v.err 5948 } 5949 5950 // monitor runs in a separate goroutine and actively pulls the next point. 5951 func (itr *unsignedParallelIterator) monitor() { 5952 defer close(itr.ch) 5953 defer itr.wg.Done() 5954 5955 for { 5956 // Read next point. 5957 p, err := itr.input.Next() 5958 if p != nil { 5959 p = p.Clone() 5960 } 5961 5962 select { 5963 case <-itr.closing: 5964 return 5965 case itr.ch <- unsignedPointError{point: p, err: err}: 5966 } 5967 } 5968 } 5969 5970 type unsignedPointError struct { 5971 point *UnsignedPoint 5972 err error 5973 } 5974 5975 // unsignedLimitIterator represents an iterator that limits points per group. 5976 type unsignedLimitIterator struct { 5977 input UnsignedIterator 5978 opt IteratorOptions 5979 n int 5980 5981 prev struct { 5982 name string 5983 tags Tags 5984 } 5985 } 5986 5987 // newUnsignedLimitIterator returns a new instance of unsignedLimitIterator. 5988 func newUnsignedLimitIterator(input UnsignedIterator, opt IteratorOptions) *unsignedLimitIterator { 5989 return &unsignedLimitIterator{ 5990 input: input, 5991 opt: opt, 5992 } 5993 } 5994 5995 // Stats returns stats from the underlying iterator. 5996 func (itr *unsignedLimitIterator) Stats() IteratorStats { return itr.input.Stats() } 5997 5998 // Close closes the underlying iterators. 5999 func (itr *unsignedLimitIterator) Close() error { return itr.input.Close() } 6000 6001 // Next returns the next point from the iterator. 6002 func (itr *unsignedLimitIterator) Next() (*UnsignedPoint, error) { 6003 for { 6004 p, err := itr.input.Next() 6005 if p == nil || err != nil { 6006 return nil, err 6007 } 6008 6009 // Reset window and counter if a new window is encountered. 6010 if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) { 6011 itr.prev.name = p.Name 6012 itr.prev.tags = p.Tags 6013 itr.n = 0 6014 } 6015 6016 // Increment counter. 6017 itr.n++ 6018 6019 // Read next point if not beyond the offset. 6020 if itr.n <= itr.opt.Offset { 6021 continue 6022 } 6023 6024 // Read next point if we're beyond the limit. 6025 if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit { 6026 continue 6027 } 6028 6029 return p, nil 6030 } 6031 } 6032 6033 type unsignedFillIterator struct { 6034 input *bufUnsignedIterator 6035 prev UnsignedPoint 6036 startTime int64 6037 endTime int64 6038 auxFields []interface{} 6039 init bool 6040 opt IteratorOptions 6041 6042 window struct { 6043 name string 6044 tags Tags 6045 time int64 6046 offset int64 6047 } 6048 } 6049 6050 func newUnsignedFillIterator(input UnsignedIterator, expr influxql.Expr, opt IteratorOptions) *unsignedFillIterator { 6051 if opt.Fill == influxql.NullFill { 6052 if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" { 6053 opt.Fill = influxql.NumberFill 6054 opt.FillValue = uint64(0) 6055 } 6056 } 6057 6058 var startTime, endTime int64 6059 if opt.Ascending { 6060 startTime, _ = opt.Window(opt.StartTime) 6061 endTime, _ = opt.Window(opt.EndTime) 6062 } else { 6063 startTime, _ = opt.Window(opt.EndTime) 6064 endTime, _ = opt.Window(opt.StartTime) 6065 } 6066 6067 var auxFields []interface{} 6068 if len(opt.Aux) > 0 { 6069 auxFields = make([]interface{}, len(opt.Aux)) 6070 } 6071 6072 return &unsignedFillIterator{ 6073 input: newBufUnsignedIterator(input), 6074 prev: UnsignedPoint{Nil: true}, 6075 startTime: startTime, 6076 endTime: endTime, 6077 auxFields: auxFields, 6078 opt: opt, 6079 } 6080 } 6081 6082 func (itr *unsignedFillIterator) Stats() IteratorStats { return itr.input.Stats() } 6083 func (itr *unsignedFillIterator) Close() error { return itr.input.Close() } 6084 6085 func (itr *unsignedFillIterator) Next() (*UnsignedPoint, error) { 6086 if !itr.init { 6087 p, err := itr.input.peek() 6088 if p == nil || err != nil { 6089 return nil, err 6090 } 6091 itr.window.name, itr.window.tags = p.Name, p.Tags 6092 itr.window.time = itr.startTime 6093 if itr.startTime == influxql.MinTime { 6094 itr.window.time, _ = itr.opt.Window(p.Time) 6095 } 6096 if itr.opt.Location != nil { 6097 _, itr.window.offset = itr.opt.Zone(itr.window.time) 6098 } 6099 itr.init = true 6100 } 6101 6102 p, err := itr.input.Next() 6103 if err != nil { 6104 return nil, err 6105 } 6106 6107 // Check if the next point is outside of our window or is nil. 6108 if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() { 6109 // If we are inside of an interval, unread the point and continue below to 6110 // constructing a new point. 6111 if itr.opt.Ascending && itr.window.time <= itr.endTime { 6112 itr.input.unread(p) 6113 p = nil 6114 goto CONSTRUCT 6115 } else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime { 6116 itr.input.unread(p) 6117 p = nil 6118 goto CONSTRUCT 6119 } 6120 6121 // We are *not* in a current interval. If there is no next point, 6122 // we are at the end of all intervals. 6123 if p == nil { 6124 return nil, nil 6125 } 6126 6127 // Set the new interval. 6128 itr.window.name, itr.window.tags = p.Name, p.Tags 6129 itr.window.time = itr.startTime 6130 if itr.window.time == influxql.MinTime { 6131 itr.window.time, _ = itr.opt.Window(p.Time) 6132 } 6133 if itr.opt.Location != nil { 6134 _, itr.window.offset = itr.opt.Zone(itr.window.time) 6135 } 6136 itr.prev = UnsignedPoint{Nil: true} 6137 } 6138 6139 // Check if the point is our next expected point. 6140 CONSTRUCT: 6141 if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) { 6142 if p != nil { 6143 itr.input.unread(p) 6144 } 6145 6146 p = &UnsignedPoint{ 6147 Name: itr.window.name, 6148 Tags: itr.window.tags, 6149 Time: itr.window.time, 6150 Aux: itr.auxFields, 6151 } 6152 6153 switch itr.opt.Fill { 6154 case influxql.LinearFill: 6155 if !itr.prev.Nil { 6156 next, err := itr.input.peek() 6157 if err != nil { 6158 return nil, err 6159 } else if next != nil && next.Name == itr.window.name && next.Tags.ID() == itr.window.tags.ID() { 6160 interval := int64(itr.opt.Interval.Duration) 6161 start := itr.window.time / interval 6162 p.Value = linearUnsigned(start, itr.prev.Time/interval, next.Time/interval, itr.prev.Value, next.Value) 6163 } else { 6164 p.Nil = true 6165 } 6166 } else { 6167 p.Nil = true 6168 } 6169 6170 case influxql.NullFill: 6171 p.Nil = true 6172 case influxql.NumberFill: 6173 p.Value, _ = castToUnsigned(itr.opt.FillValue) 6174 case influxql.PreviousFill: 6175 if !itr.prev.Nil { 6176 p.Value = itr.prev.Value 6177 p.Nil = itr.prev.Nil 6178 } else { 6179 p.Nil = true 6180 } 6181 } 6182 } else { 6183 itr.prev = *p 6184 } 6185 6186 // Advance the expected time. Do not advance to a new window here 6187 // as there may be lingering points with the same timestamp in the previous 6188 // window. 6189 if itr.opt.Ascending { 6190 itr.window.time += int64(itr.opt.Interval.Duration) 6191 } else { 6192 itr.window.time -= int64(itr.opt.Interval.Duration) 6193 } 6194 6195 // Check to see if we have passed over an offset change and adjust the time 6196 // to account for this new offset. 6197 if itr.opt.Location != nil { 6198 if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset { 6199 diff := itr.window.offset - offset 6200 if abs(diff) < int64(itr.opt.Interval.Duration) { 6201 itr.window.time += diff 6202 } 6203 itr.window.offset = offset 6204 } 6205 } 6206 return p, nil 6207 } 6208 6209 // unsignedIntervalIterator represents a unsigned implementation of IntervalIterator. 6210 type unsignedIntervalIterator struct { 6211 input UnsignedIterator 6212 opt IteratorOptions 6213 } 6214 6215 func newUnsignedIntervalIterator(input UnsignedIterator, opt IteratorOptions) *unsignedIntervalIterator { 6216 return &unsignedIntervalIterator{input: input, opt: opt} 6217 } 6218 6219 func (itr *unsignedIntervalIterator) Stats() IteratorStats { return itr.input.Stats() } 6220 func (itr *unsignedIntervalIterator) Close() error { return itr.input.Close() } 6221 6222 func (itr *unsignedIntervalIterator) Next() (*UnsignedPoint, error) { 6223 p, err := itr.input.Next() 6224 if p == nil || err != nil { 6225 return nil, err 6226 } 6227 p.Time, _ = itr.opt.Window(p.Time) 6228 // If we see the minimum allowable time, set the time to zero so we don't 6229 // break the default returned time for aggregate queries without times. 6230 if p.Time == influxql.MinTime { 6231 p.Time = 0 6232 } 6233 return p, nil 6234 } 6235 6236 // unsignedInterruptIterator represents a unsigned implementation of InterruptIterator. 6237 type unsignedInterruptIterator struct { 6238 input UnsignedIterator 6239 closing <-chan struct{} 6240 count int 6241 } 6242 6243 func newUnsignedInterruptIterator(input UnsignedIterator, closing <-chan struct{}) *unsignedInterruptIterator { 6244 return &unsignedInterruptIterator{input: input, closing: closing} 6245 } 6246 6247 func (itr *unsignedInterruptIterator) Stats() IteratorStats { return itr.input.Stats() } 6248 func (itr *unsignedInterruptIterator) Close() error { return itr.input.Close() } 6249 6250 func (itr *unsignedInterruptIterator) Next() (*UnsignedPoint, error) { 6251 // Only check if the channel is closed every N points. This 6252 // intentionally checks on both 0 and N so that if the iterator 6253 // has been interrupted before the first point is emitted it will 6254 // not emit any points. 6255 if itr.count&0xFF == 0xFF { 6256 select { 6257 case <-itr.closing: 6258 return nil, itr.Close() 6259 default: 6260 // Reset iterator count to zero and fall through to emit the next point. 6261 itr.count = 0 6262 } 6263 } 6264 6265 // Increment the counter for every point read. 6266 itr.count++ 6267 return itr.input.Next() 6268 } 6269 6270 // unsignedCloseInterruptIterator represents a unsigned implementation of CloseInterruptIterator. 6271 type unsignedCloseInterruptIterator struct { 6272 input UnsignedIterator 6273 closing <-chan struct{} 6274 done chan struct{} 6275 once sync.Once 6276 } 6277 6278 func newUnsignedCloseInterruptIterator(input UnsignedIterator, closing <-chan struct{}) *unsignedCloseInterruptIterator { 6279 itr := &unsignedCloseInterruptIterator{ 6280 input: input, 6281 closing: closing, 6282 done: make(chan struct{}), 6283 } 6284 go itr.monitor() 6285 return itr 6286 } 6287 6288 func (itr *unsignedCloseInterruptIterator) monitor() { 6289 select { 6290 case <-itr.closing: 6291 itr.Close() 6292 case <-itr.done: 6293 } 6294 } 6295 6296 func (itr *unsignedCloseInterruptIterator) Stats() IteratorStats { 6297 return itr.input.Stats() 6298 } 6299 6300 func (itr *unsignedCloseInterruptIterator) Close() error { 6301 itr.once.Do(func() { 6302 close(itr.done) 6303 itr.input.Close() 6304 }) 6305 return nil 6306 } 6307 6308 func (itr *unsignedCloseInterruptIterator) Next() (*UnsignedPoint, error) { 6309 p, err := itr.input.Next() 6310 if err != nil { 6311 // Check if the iterator was closed. 6312 select { 6313 case <-itr.done: 6314 return nil, nil 6315 default: 6316 return nil, err 6317 } 6318 } 6319 return p, nil 6320 } 6321 6322 // unsignedReduceFloatIterator executes a reducer for every interval and buffers the result. 6323 type unsignedReduceFloatIterator struct { 6324 input *bufUnsignedIterator 6325 create func() (UnsignedPointAggregator, FloatPointEmitter) 6326 dims []string 6327 opt IteratorOptions 6328 points []FloatPoint 6329 keepTags bool 6330 } 6331 6332 func newUnsignedReduceFloatIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, FloatPointEmitter)) *unsignedReduceFloatIterator { 6333 return &unsignedReduceFloatIterator{ 6334 input: newBufUnsignedIterator(input), 6335 create: createFn, 6336 dims: opt.GetDimensions(), 6337 opt: opt, 6338 } 6339 } 6340 6341 // Stats returns stats from the input iterator. 6342 func (itr *unsignedReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() } 6343 6344 // Close closes the iterator and all child iterators. 6345 func (itr *unsignedReduceFloatIterator) Close() error { return itr.input.Close() } 6346 6347 // Next returns the minimum value for the next available interval. 6348 func (itr *unsignedReduceFloatIterator) Next() (*FloatPoint, error) { 6349 // Calculate next window if we have no more points. 6350 if len(itr.points) == 0 { 6351 var err error 6352 itr.points, err = itr.reduce() 6353 if len(itr.points) == 0 { 6354 return nil, err 6355 } 6356 } 6357 6358 // Pop next point off the stack. 6359 p := &itr.points[len(itr.points)-1] 6360 itr.points = itr.points[:len(itr.points)-1] 6361 return p, nil 6362 } 6363 6364 // unsignedReduceFloatPoint stores the reduced data for a name/tag combination. 6365 type unsignedReduceFloatPoint struct { 6366 Name string 6367 Tags Tags 6368 Aggregator UnsignedPointAggregator 6369 Emitter FloatPointEmitter 6370 } 6371 6372 // reduce executes fn once for every point in the next window. 6373 // The previous value for the dimension is passed to fn. 6374 func (itr *unsignedReduceFloatIterator) reduce() ([]FloatPoint, error) { 6375 // Calculate next window. 6376 var ( 6377 startTime, endTime int64 6378 window struct { 6379 name string 6380 tags string 6381 } 6382 ) 6383 for { 6384 p, err := itr.input.Next() 6385 if err != nil || p == nil { 6386 return nil, err 6387 } else if p.Nil { 6388 continue 6389 } 6390 6391 // Unread the point so it can be processed. 6392 itr.input.unread(p) 6393 startTime, endTime = itr.opt.Window(p.Time) 6394 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 6395 break 6396 } 6397 6398 // Create points by tags. 6399 m := make(map[string]*unsignedReduceFloatPoint) 6400 for { 6401 // Read next point. 6402 curr, err := itr.input.NextInWindow(startTime, endTime) 6403 if err != nil { 6404 return nil, err 6405 } else if curr == nil { 6406 break 6407 } else if curr.Nil { 6408 continue 6409 } else if curr.Name != window.name { 6410 itr.input.unread(curr) 6411 break 6412 } 6413 6414 // Ensure this point is within the same final window. 6415 if curr.Name != window.name { 6416 itr.input.unread(curr) 6417 break 6418 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 6419 itr.input.unread(curr) 6420 break 6421 } 6422 6423 // Retrieve the tags on this point for this level of the query. 6424 // This may be different than the bucket dimensions. 6425 tags := curr.Tags.Subset(itr.dims) 6426 id := tags.ID() 6427 6428 // Retrieve the aggregator for this name/tag combination or create one. 6429 rp := m[id] 6430 if rp == nil { 6431 aggregator, emitter := itr.create() 6432 rp = &unsignedReduceFloatPoint{ 6433 Name: curr.Name, 6434 Tags: tags, 6435 Aggregator: aggregator, 6436 Emitter: emitter, 6437 } 6438 m[id] = rp 6439 } 6440 rp.Aggregator.AggregateUnsigned(curr) 6441 } 6442 6443 keys := make([]string, 0, len(m)) 6444 for k := range m { 6445 keys = append(keys, k) 6446 } 6447 6448 // Reverse sort points by name & tag. 6449 // This ensures a consistent order of output. 6450 if len(keys) > 0 { 6451 var sorted sort.Interface = sort.StringSlice(keys) 6452 if itr.opt.Ascending { 6453 sorted = sort.Reverse(sorted) 6454 } 6455 sort.Sort(sorted) 6456 } 6457 6458 // Assume the points are already sorted until proven otherwise. 6459 sortedByTime := true 6460 // Emit the points for each name & tag combination. 6461 a := make([]FloatPoint, 0, len(m)) 6462 for _, k := range keys { 6463 rp := m[k] 6464 points := rp.Emitter.Emit() 6465 for i := len(points) - 1; i >= 0; i-- { 6466 points[i].Name = rp.Name 6467 if !itr.keepTags { 6468 points[i].Tags = rp.Tags 6469 } 6470 // Set the points time to the interval time if the reducer didn't provide one. 6471 if points[i].Time == ZeroTime { 6472 points[i].Time = startTime 6473 } else { 6474 sortedByTime = false 6475 } 6476 a = append(a, points[i]) 6477 } 6478 } 6479 // Points may be out of order. Perform a stable sort by time if requested. 6480 if !sortedByTime && itr.opt.Ordered { 6481 var sorted sort.Interface = floatPointsByTime(a) 6482 if itr.opt.Ascending { 6483 sorted = sort.Reverse(sorted) 6484 } 6485 sort.Stable(sorted) 6486 } 6487 return a, nil 6488 } 6489 6490 // unsignedStreamFloatIterator streams inputs into the iterator and emits points gradually. 6491 type unsignedStreamFloatIterator struct { 6492 input *bufUnsignedIterator 6493 create func() (UnsignedPointAggregator, FloatPointEmitter) 6494 dims []string 6495 opt IteratorOptions 6496 m map[string]*unsignedReduceFloatPoint 6497 points []FloatPoint 6498 } 6499 6500 // newUnsignedStreamFloatIterator returns a new instance of unsignedStreamFloatIterator. 6501 func newUnsignedStreamFloatIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, FloatPointEmitter), opt IteratorOptions) *unsignedStreamFloatIterator { 6502 return &unsignedStreamFloatIterator{ 6503 input: newBufUnsignedIterator(input), 6504 create: createFn, 6505 dims: opt.GetDimensions(), 6506 opt: opt, 6507 m: make(map[string]*unsignedReduceFloatPoint), 6508 } 6509 } 6510 6511 // Stats returns stats from the input iterator. 6512 func (itr *unsignedStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() } 6513 6514 // Close closes the iterator and all child iterators. 6515 func (itr *unsignedStreamFloatIterator) Close() error { return itr.input.Close() } 6516 6517 // Next returns the next value for the stream iterator. 6518 func (itr *unsignedStreamFloatIterator) Next() (*FloatPoint, error) { 6519 // Calculate next window if we have no more points. 6520 if len(itr.points) == 0 { 6521 var err error 6522 itr.points, err = itr.reduce() 6523 if len(itr.points) == 0 { 6524 return nil, err 6525 } 6526 } 6527 6528 // Pop next point off the stack. 6529 p := &itr.points[len(itr.points)-1] 6530 itr.points = itr.points[:len(itr.points)-1] 6531 return p, nil 6532 } 6533 6534 // reduce creates and manages aggregators for every point from the input. 6535 // After aggregating a point, it always tries to emit a value using the emitter. 6536 func (itr *unsignedStreamFloatIterator) reduce() ([]FloatPoint, error) { 6537 // We have already read all of the input points. 6538 if itr.m == nil { 6539 return nil, nil 6540 } 6541 6542 for { 6543 // Read next point. 6544 curr, err := itr.input.Next() 6545 if err != nil { 6546 return nil, err 6547 } else if curr == nil { 6548 // Close all of the aggregators to flush any remaining points to emit. 6549 var points []FloatPoint 6550 for _, rp := range itr.m { 6551 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 6552 if err := aggregator.Close(); err != nil { 6553 return nil, err 6554 } 6555 6556 pts := rp.Emitter.Emit() 6557 if len(pts) == 0 { 6558 continue 6559 } 6560 6561 for i := range pts { 6562 pts[i].Name = rp.Name 6563 pts[i].Tags = rp.Tags 6564 } 6565 points = append(points, pts...) 6566 } 6567 } 6568 6569 // Eliminate the aggregators and emitters. 6570 itr.m = nil 6571 return points, nil 6572 } else if curr.Nil { 6573 continue 6574 } 6575 tags := curr.Tags.Subset(itr.dims) 6576 6577 id := curr.Name 6578 if len(tags.m) > 0 { 6579 id += "\x00" + tags.ID() 6580 } 6581 6582 // Retrieve the aggregator for this name/tag combination or create one. 6583 rp := itr.m[id] 6584 if rp == nil { 6585 aggregator, emitter := itr.create() 6586 rp = &unsignedReduceFloatPoint{ 6587 Name: curr.Name, 6588 Tags: tags, 6589 Aggregator: aggregator, 6590 Emitter: emitter, 6591 } 6592 itr.m[id] = rp 6593 } 6594 rp.Aggregator.AggregateUnsigned(curr) 6595 6596 // Attempt to emit points from the aggregator. 6597 points := rp.Emitter.Emit() 6598 if len(points) == 0 { 6599 continue 6600 } 6601 6602 for i := range points { 6603 points[i].Name = rp.Name 6604 points[i].Tags = rp.Tags 6605 } 6606 return points, nil 6607 } 6608 } 6609 6610 // unsignedReduceIntegerIterator executes a reducer for every interval and buffers the result. 6611 type unsignedReduceIntegerIterator struct { 6612 input *bufUnsignedIterator 6613 create func() (UnsignedPointAggregator, IntegerPointEmitter) 6614 dims []string 6615 opt IteratorOptions 6616 points []IntegerPoint 6617 keepTags bool 6618 } 6619 6620 func newUnsignedReduceIntegerIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, IntegerPointEmitter)) *unsignedReduceIntegerIterator { 6621 return &unsignedReduceIntegerIterator{ 6622 input: newBufUnsignedIterator(input), 6623 create: createFn, 6624 dims: opt.GetDimensions(), 6625 opt: opt, 6626 } 6627 } 6628 6629 // Stats returns stats from the input iterator. 6630 func (itr *unsignedReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() } 6631 6632 // Close closes the iterator and all child iterators. 6633 func (itr *unsignedReduceIntegerIterator) Close() error { return itr.input.Close() } 6634 6635 // Next returns the minimum value for the next available interval. 6636 func (itr *unsignedReduceIntegerIterator) Next() (*IntegerPoint, error) { 6637 // Calculate next window if we have no more points. 6638 if len(itr.points) == 0 { 6639 var err error 6640 itr.points, err = itr.reduce() 6641 if len(itr.points) == 0 { 6642 return nil, err 6643 } 6644 } 6645 6646 // Pop next point off the stack. 6647 p := &itr.points[len(itr.points)-1] 6648 itr.points = itr.points[:len(itr.points)-1] 6649 return p, nil 6650 } 6651 6652 // unsignedReduceIntegerPoint stores the reduced data for a name/tag combination. 6653 type unsignedReduceIntegerPoint struct { 6654 Name string 6655 Tags Tags 6656 Aggregator UnsignedPointAggregator 6657 Emitter IntegerPointEmitter 6658 } 6659 6660 // reduce executes fn once for every point in the next window. 6661 // The previous value for the dimension is passed to fn. 6662 func (itr *unsignedReduceIntegerIterator) reduce() ([]IntegerPoint, error) { 6663 // Calculate next window. 6664 var ( 6665 startTime, endTime int64 6666 window struct { 6667 name string 6668 tags string 6669 } 6670 ) 6671 for { 6672 p, err := itr.input.Next() 6673 if err != nil || p == nil { 6674 return nil, err 6675 } else if p.Nil { 6676 continue 6677 } 6678 6679 // Unread the point so it can be processed. 6680 itr.input.unread(p) 6681 startTime, endTime = itr.opt.Window(p.Time) 6682 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 6683 break 6684 } 6685 6686 // Create points by tags. 6687 m := make(map[string]*unsignedReduceIntegerPoint) 6688 for { 6689 // Read next point. 6690 curr, err := itr.input.NextInWindow(startTime, endTime) 6691 if err != nil { 6692 return nil, err 6693 } else if curr == nil { 6694 break 6695 } else if curr.Nil { 6696 continue 6697 } else if curr.Name != window.name { 6698 itr.input.unread(curr) 6699 break 6700 } 6701 6702 // Ensure this point is within the same final window. 6703 if curr.Name != window.name { 6704 itr.input.unread(curr) 6705 break 6706 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 6707 itr.input.unread(curr) 6708 break 6709 } 6710 6711 // Retrieve the tags on this point for this level of the query. 6712 // This may be different than the bucket dimensions. 6713 tags := curr.Tags.Subset(itr.dims) 6714 id := tags.ID() 6715 6716 // Retrieve the aggregator for this name/tag combination or create one. 6717 rp := m[id] 6718 if rp == nil { 6719 aggregator, emitter := itr.create() 6720 rp = &unsignedReduceIntegerPoint{ 6721 Name: curr.Name, 6722 Tags: tags, 6723 Aggregator: aggregator, 6724 Emitter: emitter, 6725 } 6726 m[id] = rp 6727 } 6728 rp.Aggregator.AggregateUnsigned(curr) 6729 } 6730 6731 keys := make([]string, 0, len(m)) 6732 for k := range m { 6733 keys = append(keys, k) 6734 } 6735 6736 // Reverse sort points by name & tag. 6737 // This ensures a consistent order of output. 6738 if len(keys) > 0 { 6739 var sorted sort.Interface = sort.StringSlice(keys) 6740 if itr.opt.Ascending { 6741 sorted = sort.Reverse(sorted) 6742 } 6743 sort.Sort(sorted) 6744 } 6745 6746 // Assume the points are already sorted until proven otherwise. 6747 sortedByTime := true 6748 // Emit the points for each name & tag combination. 6749 a := make([]IntegerPoint, 0, len(m)) 6750 for _, k := range keys { 6751 rp := m[k] 6752 points := rp.Emitter.Emit() 6753 for i := len(points) - 1; i >= 0; i-- { 6754 points[i].Name = rp.Name 6755 if !itr.keepTags { 6756 points[i].Tags = rp.Tags 6757 } 6758 // Set the points time to the interval time if the reducer didn't provide one. 6759 if points[i].Time == ZeroTime { 6760 points[i].Time = startTime 6761 } else { 6762 sortedByTime = false 6763 } 6764 a = append(a, points[i]) 6765 } 6766 } 6767 // Points may be out of order. Perform a stable sort by time if requested. 6768 if !sortedByTime && itr.opt.Ordered { 6769 var sorted sort.Interface = integerPointsByTime(a) 6770 if itr.opt.Ascending { 6771 sorted = sort.Reverse(sorted) 6772 } 6773 sort.Stable(sorted) 6774 } 6775 return a, nil 6776 } 6777 6778 // unsignedStreamIntegerIterator streams inputs into the iterator and emits points gradually. 6779 type unsignedStreamIntegerIterator struct { 6780 input *bufUnsignedIterator 6781 create func() (UnsignedPointAggregator, IntegerPointEmitter) 6782 dims []string 6783 opt IteratorOptions 6784 m map[string]*unsignedReduceIntegerPoint 6785 points []IntegerPoint 6786 } 6787 6788 // newUnsignedStreamIntegerIterator returns a new instance of unsignedStreamIntegerIterator. 6789 func newUnsignedStreamIntegerIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, IntegerPointEmitter), opt IteratorOptions) *unsignedStreamIntegerIterator { 6790 return &unsignedStreamIntegerIterator{ 6791 input: newBufUnsignedIterator(input), 6792 create: createFn, 6793 dims: opt.GetDimensions(), 6794 opt: opt, 6795 m: make(map[string]*unsignedReduceIntegerPoint), 6796 } 6797 } 6798 6799 // Stats returns stats from the input iterator. 6800 func (itr *unsignedStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() } 6801 6802 // Close closes the iterator and all child iterators. 6803 func (itr *unsignedStreamIntegerIterator) Close() error { return itr.input.Close() } 6804 6805 // Next returns the next value for the stream iterator. 6806 func (itr *unsignedStreamIntegerIterator) Next() (*IntegerPoint, error) { 6807 // Calculate next window if we have no more points. 6808 if len(itr.points) == 0 { 6809 var err error 6810 itr.points, err = itr.reduce() 6811 if len(itr.points) == 0 { 6812 return nil, err 6813 } 6814 } 6815 6816 // Pop next point off the stack. 6817 p := &itr.points[len(itr.points)-1] 6818 itr.points = itr.points[:len(itr.points)-1] 6819 return p, nil 6820 } 6821 6822 // reduce creates and manages aggregators for every point from the input. 6823 // After aggregating a point, it always tries to emit a value using the emitter. 6824 func (itr *unsignedStreamIntegerIterator) reduce() ([]IntegerPoint, error) { 6825 // We have already read all of the input points. 6826 if itr.m == nil { 6827 return nil, nil 6828 } 6829 6830 for { 6831 // Read next point. 6832 curr, err := itr.input.Next() 6833 if err != nil { 6834 return nil, err 6835 } else if curr == nil { 6836 // Close all of the aggregators to flush any remaining points to emit. 6837 var points []IntegerPoint 6838 for _, rp := range itr.m { 6839 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 6840 if err := aggregator.Close(); err != nil { 6841 return nil, err 6842 } 6843 6844 pts := rp.Emitter.Emit() 6845 if len(pts) == 0 { 6846 continue 6847 } 6848 6849 for i := range pts { 6850 pts[i].Name = rp.Name 6851 pts[i].Tags = rp.Tags 6852 } 6853 points = append(points, pts...) 6854 } 6855 } 6856 6857 // Eliminate the aggregators and emitters. 6858 itr.m = nil 6859 return points, nil 6860 } else if curr.Nil { 6861 continue 6862 } 6863 tags := curr.Tags.Subset(itr.dims) 6864 6865 id := curr.Name 6866 if len(tags.m) > 0 { 6867 id += "\x00" + tags.ID() 6868 } 6869 6870 // Retrieve the aggregator for this name/tag combination or create one. 6871 rp := itr.m[id] 6872 if rp == nil { 6873 aggregator, emitter := itr.create() 6874 rp = &unsignedReduceIntegerPoint{ 6875 Name: curr.Name, 6876 Tags: tags, 6877 Aggregator: aggregator, 6878 Emitter: emitter, 6879 } 6880 itr.m[id] = rp 6881 } 6882 rp.Aggregator.AggregateUnsigned(curr) 6883 6884 // Attempt to emit points from the aggregator. 6885 points := rp.Emitter.Emit() 6886 if len(points) == 0 { 6887 continue 6888 } 6889 6890 for i := range points { 6891 points[i].Name = rp.Name 6892 points[i].Tags = rp.Tags 6893 } 6894 return points, nil 6895 } 6896 } 6897 6898 // unsignedReduceUnsignedIterator executes a reducer for every interval and buffers the result. 6899 type unsignedReduceUnsignedIterator struct { 6900 input *bufUnsignedIterator 6901 create func() (UnsignedPointAggregator, UnsignedPointEmitter) 6902 dims []string 6903 opt IteratorOptions 6904 points []UnsignedPoint 6905 keepTags bool 6906 } 6907 6908 func newUnsignedReduceUnsignedIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, UnsignedPointEmitter)) *unsignedReduceUnsignedIterator { 6909 return &unsignedReduceUnsignedIterator{ 6910 input: newBufUnsignedIterator(input), 6911 create: createFn, 6912 dims: opt.GetDimensions(), 6913 opt: opt, 6914 } 6915 } 6916 6917 // Stats returns stats from the input iterator. 6918 func (itr *unsignedReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() } 6919 6920 // Close closes the iterator and all child iterators. 6921 func (itr *unsignedReduceUnsignedIterator) Close() error { return itr.input.Close() } 6922 6923 // Next returns the minimum value for the next available interval. 6924 func (itr *unsignedReduceUnsignedIterator) Next() (*UnsignedPoint, error) { 6925 // Calculate next window if we have no more points. 6926 if len(itr.points) == 0 { 6927 var err error 6928 itr.points, err = itr.reduce() 6929 if len(itr.points) == 0 { 6930 return nil, err 6931 } 6932 } 6933 6934 // Pop next point off the stack. 6935 p := &itr.points[len(itr.points)-1] 6936 itr.points = itr.points[:len(itr.points)-1] 6937 return p, nil 6938 } 6939 6940 // unsignedReduceUnsignedPoint stores the reduced data for a name/tag combination. 6941 type unsignedReduceUnsignedPoint struct { 6942 Name string 6943 Tags Tags 6944 Aggregator UnsignedPointAggregator 6945 Emitter UnsignedPointEmitter 6946 } 6947 6948 // reduce executes fn once for every point in the next window. 6949 // The previous value for the dimension is passed to fn. 6950 func (itr *unsignedReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) { 6951 // Calculate next window. 6952 var ( 6953 startTime, endTime int64 6954 window struct { 6955 name string 6956 tags string 6957 } 6958 ) 6959 for { 6960 p, err := itr.input.Next() 6961 if err != nil || p == nil { 6962 return nil, err 6963 } else if p.Nil { 6964 continue 6965 } 6966 6967 // Unread the point so it can be processed. 6968 itr.input.unread(p) 6969 startTime, endTime = itr.opt.Window(p.Time) 6970 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 6971 break 6972 } 6973 6974 // Create points by tags. 6975 m := make(map[string]*unsignedReduceUnsignedPoint) 6976 for { 6977 // Read next point. 6978 curr, err := itr.input.NextInWindow(startTime, endTime) 6979 if err != nil { 6980 return nil, err 6981 } else if curr == nil { 6982 break 6983 } else if curr.Nil { 6984 continue 6985 } else if curr.Name != window.name { 6986 itr.input.unread(curr) 6987 break 6988 } 6989 6990 // Ensure this point is within the same final window. 6991 if curr.Name != window.name { 6992 itr.input.unread(curr) 6993 break 6994 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 6995 itr.input.unread(curr) 6996 break 6997 } 6998 6999 // Retrieve the tags on this point for this level of the query. 7000 // This may be different than the bucket dimensions. 7001 tags := curr.Tags.Subset(itr.dims) 7002 id := tags.ID() 7003 7004 // Retrieve the aggregator for this name/tag combination or create one. 7005 rp := m[id] 7006 if rp == nil { 7007 aggregator, emitter := itr.create() 7008 rp = &unsignedReduceUnsignedPoint{ 7009 Name: curr.Name, 7010 Tags: tags, 7011 Aggregator: aggregator, 7012 Emitter: emitter, 7013 } 7014 m[id] = rp 7015 } 7016 rp.Aggregator.AggregateUnsigned(curr) 7017 } 7018 7019 keys := make([]string, 0, len(m)) 7020 for k := range m { 7021 keys = append(keys, k) 7022 } 7023 7024 // Reverse sort points by name & tag. 7025 // This ensures a consistent order of output. 7026 if len(keys) > 0 { 7027 var sorted sort.Interface = sort.StringSlice(keys) 7028 if itr.opt.Ascending { 7029 sorted = sort.Reverse(sorted) 7030 } 7031 sort.Sort(sorted) 7032 } 7033 7034 // Assume the points are already sorted until proven otherwise. 7035 sortedByTime := true 7036 // Emit the points for each name & tag combination. 7037 a := make([]UnsignedPoint, 0, len(m)) 7038 for _, k := range keys { 7039 rp := m[k] 7040 points := rp.Emitter.Emit() 7041 for i := len(points) - 1; i >= 0; i-- { 7042 points[i].Name = rp.Name 7043 if !itr.keepTags { 7044 points[i].Tags = rp.Tags 7045 } 7046 // Set the points time to the interval time if the reducer didn't provide one. 7047 if points[i].Time == ZeroTime { 7048 points[i].Time = startTime 7049 } else { 7050 sortedByTime = false 7051 } 7052 a = append(a, points[i]) 7053 } 7054 } 7055 // Points may be out of order. Perform a stable sort by time if requested. 7056 if !sortedByTime && itr.opt.Ordered { 7057 var sorted sort.Interface = unsignedPointsByTime(a) 7058 if itr.opt.Ascending { 7059 sorted = sort.Reverse(sorted) 7060 } 7061 sort.Stable(sorted) 7062 } 7063 return a, nil 7064 } 7065 7066 // unsignedStreamUnsignedIterator streams inputs into the iterator and emits points gradually. 7067 type unsignedStreamUnsignedIterator struct { 7068 input *bufUnsignedIterator 7069 create func() (UnsignedPointAggregator, UnsignedPointEmitter) 7070 dims []string 7071 opt IteratorOptions 7072 m map[string]*unsignedReduceUnsignedPoint 7073 points []UnsignedPoint 7074 } 7075 7076 // newUnsignedStreamUnsignedIterator returns a new instance of unsignedStreamUnsignedIterator. 7077 func newUnsignedStreamUnsignedIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *unsignedStreamUnsignedIterator { 7078 return &unsignedStreamUnsignedIterator{ 7079 input: newBufUnsignedIterator(input), 7080 create: createFn, 7081 dims: opt.GetDimensions(), 7082 opt: opt, 7083 m: make(map[string]*unsignedReduceUnsignedPoint), 7084 } 7085 } 7086 7087 // Stats returns stats from the input iterator. 7088 func (itr *unsignedStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() } 7089 7090 // Close closes the iterator and all child iterators. 7091 func (itr *unsignedStreamUnsignedIterator) Close() error { return itr.input.Close() } 7092 7093 // Next returns the next value for the stream iterator. 7094 func (itr *unsignedStreamUnsignedIterator) Next() (*UnsignedPoint, error) { 7095 // Calculate next window if we have no more points. 7096 if len(itr.points) == 0 { 7097 var err error 7098 itr.points, err = itr.reduce() 7099 if len(itr.points) == 0 { 7100 return nil, err 7101 } 7102 } 7103 7104 // Pop next point off the stack. 7105 p := &itr.points[len(itr.points)-1] 7106 itr.points = itr.points[:len(itr.points)-1] 7107 return p, nil 7108 } 7109 7110 // reduce creates and manages aggregators for every point from the input. 7111 // After aggregating a point, it always tries to emit a value using the emitter. 7112 func (itr *unsignedStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) { 7113 // We have already read all of the input points. 7114 if itr.m == nil { 7115 return nil, nil 7116 } 7117 7118 for { 7119 // Read next point. 7120 curr, err := itr.input.Next() 7121 if err != nil { 7122 return nil, err 7123 } else if curr == nil { 7124 // Close all of the aggregators to flush any remaining points to emit. 7125 var points []UnsignedPoint 7126 for _, rp := range itr.m { 7127 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 7128 if err := aggregator.Close(); err != nil { 7129 return nil, err 7130 } 7131 7132 pts := rp.Emitter.Emit() 7133 if len(pts) == 0 { 7134 continue 7135 } 7136 7137 for i := range pts { 7138 pts[i].Name = rp.Name 7139 pts[i].Tags = rp.Tags 7140 } 7141 points = append(points, pts...) 7142 } 7143 } 7144 7145 // Eliminate the aggregators and emitters. 7146 itr.m = nil 7147 return points, nil 7148 } else if curr.Nil { 7149 continue 7150 } 7151 tags := curr.Tags.Subset(itr.dims) 7152 7153 id := curr.Name 7154 if len(tags.m) > 0 { 7155 id += "\x00" + tags.ID() 7156 } 7157 7158 // Retrieve the aggregator for this name/tag combination or create one. 7159 rp := itr.m[id] 7160 if rp == nil { 7161 aggregator, emitter := itr.create() 7162 rp = &unsignedReduceUnsignedPoint{ 7163 Name: curr.Name, 7164 Tags: tags, 7165 Aggregator: aggregator, 7166 Emitter: emitter, 7167 } 7168 itr.m[id] = rp 7169 } 7170 rp.Aggregator.AggregateUnsigned(curr) 7171 7172 // Attempt to emit points from the aggregator. 7173 points := rp.Emitter.Emit() 7174 if len(points) == 0 { 7175 continue 7176 } 7177 7178 for i := range points { 7179 points[i].Name = rp.Name 7180 points[i].Tags = rp.Tags 7181 } 7182 return points, nil 7183 } 7184 } 7185 7186 // unsignedReduceStringIterator executes a reducer for every interval and buffers the result. 7187 type unsignedReduceStringIterator struct { 7188 input *bufUnsignedIterator 7189 create func() (UnsignedPointAggregator, StringPointEmitter) 7190 dims []string 7191 opt IteratorOptions 7192 points []StringPoint 7193 keepTags bool 7194 } 7195 7196 func newUnsignedReduceStringIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, StringPointEmitter)) *unsignedReduceStringIterator { 7197 return &unsignedReduceStringIterator{ 7198 input: newBufUnsignedIterator(input), 7199 create: createFn, 7200 dims: opt.GetDimensions(), 7201 opt: opt, 7202 } 7203 } 7204 7205 // Stats returns stats from the input iterator. 7206 func (itr *unsignedReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() } 7207 7208 // Close closes the iterator and all child iterators. 7209 func (itr *unsignedReduceStringIterator) Close() error { return itr.input.Close() } 7210 7211 // Next returns the minimum value for the next available interval. 7212 func (itr *unsignedReduceStringIterator) Next() (*StringPoint, error) { 7213 // Calculate next window if we have no more points. 7214 if len(itr.points) == 0 { 7215 var err error 7216 itr.points, err = itr.reduce() 7217 if len(itr.points) == 0 { 7218 return nil, err 7219 } 7220 } 7221 7222 // Pop next point off the stack. 7223 p := &itr.points[len(itr.points)-1] 7224 itr.points = itr.points[:len(itr.points)-1] 7225 return p, nil 7226 } 7227 7228 // unsignedReduceStringPoint stores the reduced data for a name/tag combination. 7229 type unsignedReduceStringPoint struct { 7230 Name string 7231 Tags Tags 7232 Aggregator UnsignedPointAggregator 7233 Emitter StringPointEmitter 7234 } 7235 7236 // reduce executes fn once for every point in the next window. 7237 // The previous value for the dimension is passed to fn. 7238 func (itr *unsignedReduceStringIterator) reduce() ([]StringPoint, error) { 7239 // Calculate next window. 7240 var ( 7241 startTime, endTime int64 7242 window struct { 7243 name string 7244 tags string 7245 } 7246 ) 7247 for { 7248 p, err := itr.input.Next() 7249 if err != nil || p == nil { 7250 return nil, err 7251 } else if p.Nil { 7252 continue 7253 } 7254 7255 // Unread the point so it can be processed. 7256 itr.input.unread(p) 7257 startTime, endTime = itr.opt.Window(p.Time) 7258 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 7259 break 7260 } 7261 7262 // Create points by tags. 7263 m := make(map[string]*unsignedReduceStringPoint) 7264 for { 7265 // Read next point. 7266 curr, err := itr.input.NextInWindow(startTime, endTime) 7267 if err != nil { 7268 return nil, err 7269 } else if curr == nil { 7270 break 7271 } else if curr.Nil { 7272 continue 7273 } else if curr.Name != window.name { 7274 itr.input.unread(curr) 7275 break 7276 } 7277 7278 // Ensure this point is within the same final window. 7279 if curr.Name != window.name { 7280 itr.input.unread(curr) 7281 break 7282 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 7283 itr.input.unread(curr) 7284 break 7285 } 7286 7287 // Retrieve the tags on this point for this level of the query. 7288 // This may be different than the bucket dimensions. 7289 tags := curr.Tags.Subset(itr.dims) 7290 id := tags.ID() 7291 7292 // Retrieve the aggregator for this name/tag combination or create one. 7293 rp := m[id] 7294 if rp == nil { 7295 aggregator, emitter := itr.create() 7296 rp = &unsignedReduceStringPoint{ 7297 Name: curr.Name, 7298 Tags: tags, 7299 Aggregator: aggregator, 7300 Emitter: emitter, 7301 } 7302 m[id] = rp 7303 } 7304 rp.Aggregator.AggregateUnsigned(curr) 7305 } 7306 7307 keys := make([]string, 0, len(m)) 7308 for k := range m { 7309 keys = append(keys, k) 7310 } 7311 7312 // Reverse sort points by name & tag. 7313 // This ensures a consistent order of output. 7314 if len(keys) > 0 { 7315 var sorted sort.Interface = sort.StringSlice(keys) 7316 if itr.opt.Ascending { 7317 sorted = sort.Reverse(sorted) 7318 } 7319 sort.Sort(sorted) 7320 } 7321 7322 // Assume the points are already sorted until proven otherwise. 7323 sortedByTime := true 7324 // Emit the points for each name & tag combination. 7325 a := make([]StringPoint, 0, len(m)) 7326 for _, k := range keys { 7327 rp := m[k] 7328 points := rp.Emitter.Emit() 7329 for i := len(points) - 1; i >= 0; i-- { 7330 points[i].Name = rp.Name 7331 if !itr.keepTags { 7332 points[i].Tags = rp.Tags 7333 } 7334 // Set the points time to the interval time if the reducer didn't provide one. 7335 if points[i].Time == ZeroTime { 7336 points[i].Time = startTime 7337 } else { 7338 sortedByTime = false 7339 } 7340 a = append(a, points[i]) 7341 } 7342 } 7343 // Points may be out of order. Perform a stable sort by time if requested. 7344 if !sortedByTime && itr.opt.Ordered { 7345 var sorted sort.Interface = stringPointsByTime(a) 7346 if itr.opt.Ascending { 7347 sorted = sort.Reverse(sorted) 7348 } 7349 sort.Stable(sorted) 7350 } 7351 return a, nil 7352 } 7353 7354 // unsignedStreamStringIterator streams inputs into the iterator and emits points gradually. 7355 type unsignedStreamStringIterator struct { 7356 input *bufUnsignedIterator 7357 create func() (UnsignedPointAggregator, StringPointEmitter) 7358 dims []string 7359 opt IteratorOptions 7360 m map[string]*unsignedReduceStringPoint 7361 points []StringPoint 7362 } 7363 7364 // newUnsignedStreamStringIterator returns a new instance of unsignedStreamStringIterator. 7365 func newUnsignedStreamStringIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, StringPointEmitter), opt IteratorOptions) *unsignedStreamStringIterator { 7366 return &unsignedStreamStringIterator{ 7367 input: newBufUnsignedIterator(input), 7368 create: createFn, 7369 dims: opt.GetDimensions(), 7370 opt: opt, 7371 m: make(map[string]*unsignedReduceStringPoint), 7372 } 7373 } 7374 7375 // Stats returns stats from the input iterator. 7376 func (itr *unsignedStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() } 7377 7378 // Close closes the iterator and all child iterators. 7379 func (itr *unsignedStreamStringIterator) Close() error { return itr.input.Close() } 7380 7381 // Next returns the next value for the stream iterator. 7382 func (itr *unsignedStreamStringIterator) Next() (*StringPoint, error) { 7383 // Calculate next window if we have no more points. 7384 if len(itr.points) == 0 { 7385 var err error 7386 itr.points, err = itr.reduce() 7387 if len(itr.points) == 0 { 7388 return nil, err 7389 } 7390 } 7391 7392 // Pop next point off the stack. 7393 p := &itr.points[len(itr.points)-1] 7394 itr.points = itr.points[:len(itr.points)-1] 7395 return p, nil 7396 } 7397 7398 // reduce creates and manages aggregators for every point from the input. 7399 // After aggregating a point, it always tries to emit a value using the emitter. 7400 func (itr *unsignedStreamStringIterator) reduce() ([]StringPoint, error) { 7401 // We have already read all of the input points. 7402 if itr.m == nil { 7403 return nil, nil 7404 } 7405 7406 for { 7407 // Read next point. 7408 curr, err := itr.input.Next() 7409 if err != nil { 7410 return nil, err 7411 } else if curr == nil { 7412 // Close all of the aggregators to flush any remaining points to emit. 7413 var points []StringPoint 7414 for _, rp := range itr.m { 7415 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 7416 if err := aggregator.Close(); err != nil { 7417 return nil, err 7418 } 7419 7420 pts := rp.Emitter.Emit() 7421 if len(pts) == 0 { 7422 continue 7423 } 7424 7425 for i := range pts { 7426 pts[i].Name = rp.Name 7427 pts[i].Tags = rp.Tags 7428 } 7429 points = append(points, pts...) 7430 } 7431 } 7432 7433 // Eliminate the aggregators and emitters. 7434 itr.m = nil 7435 return points, nil 7436 } else if curr.Nil { 7437 continue 7438 } 7439 tags := curr.Tags.Subset(itr.dims) 7440 7441 id := curr.Name 7442 if len(tags.m) > 0 { 7443 id += "\x00" + tags.ID() 7444 } 7445 7446 // Retrieve the aggregator for this name/tag combination or create one. 7447 rp := itr.m[id] 7448 if rp == nil { 7449 aggregator, emitter := itr.create() 7450 rp = &unsignedReduceStringPoint{ 7451 Name: curr.Name, 7452 Tags: tags, 7453 Aggregator: aggregator, 7454 Emitter: emitter, 7455 } 7456 itr.m[id] = rp 7457 } 7458 rp.Aggregator.AggregateUnsigned(curr) 7459 7460 // Attempt to emit points from the aggregator. 7461 points := rp.Emitter.Emit() 7462 if len(points) == 0 { 7463 continue 7464 } 7465 7466 for i := range points { 7467 points[i].Name = rp.Name 7468 points[i].Tags = rp.Tags 7469 } 7470 return points, nil 7471 } 7472 } 7473 7474 // unsignedReduceBooleanIterator executes a reducer for every interval and buffers the result. 7475 type unsignedReduceBooleanIterator struct { 7476 input *bufUnsignedIterator 7477 create func() (UnsignedPointAggregator, BooleanPointEmitter) 7478 dims []string 7479 opt IteratorOptions 7480 points []BooleanPoint 7481 keepTags bool 7482 } 7483 7484 func newUnsignedReduceBooleanIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, BooleanPointEmitter)) *unsignedReduceBooleanIterator { 7485 return &unsignedReduceBooleanIterator{ 7486 input: newBufUnsignedIterator(input), 7487 create: createFn, 7488 dims: opt.GetDimensions(), 7489 opt: opt, 7490 } 7491 } 7492 7493 // Stats returns stats from the input iterator. 7494 func (itr *unsignedReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() } 7495 7496 // Close closes the iterator and all child iterators. 7497 func (itr *unsignedReduceBooleanIterator) Close() error { return itr.input.Close() } 7498 7499 // Next returns the minimum value for the next available interval. 7500 func (itr *unsignedReduceBooleanIterator) Next() (*BooleanPoint, error) { 7501 // Calculate next window if we have no more points. 7502 if len(itr.points) == 0 { 7503 var err error 7504 itr.points, err = itr.reduce() 7505 if len(itr.points) == 0 { 7506 return nil, err 7507 } 7508 } 7509 7510 // Pop next point off the stack. 7511 p := &itr.points[len(itr.points)-1] 7512 itr.points = itr.points[:len(itr.points)-1] 7513 return p, nil 7514 } 7515 7516 // unsignedReduceBooleanPoint stores the reduced data for a name/tag combination. 7517 type unsignedReduceBooleanPoint struct { 7518 Name string 7519 Tags Tags 7520 Aggregator UnsignedPointAggregator 7521 Emitter BooleanPointEmitter 7522 } 7523 7524 // reduce executes fn once for every point in the next window. 7525 // The previous value for the dimension is passed to fn. 7526 func (itr *unsignedReduceBooleanIterator) reduce() ([]BooleanPoint, error) { 7527 // Calculate next window. 7528 var ( 7529 startTime, endTime int64 7530 window struct { 7531 name string 7532 tags string 7533 } 7534 ) 7535 for { 7536 p, err := itr.input.Next() 7537 if err != nil || p == nil { 7538 return nil, err 7539 } else if p.Nil { 7540 continue 7541 } 7542 7543 // Unread the point so it can be processed. 7544 itr.input.unread(p) 7545 startTime, endTime = itr.opt.Window(p.Time) 7546 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 7547 break 7548 } 7549 7550 // Create points by tags. 7551 m := make(map[string]*unsignedReduceBooleanPoint) 7552 for { 7553 // Read next point. 7554 curr, err := itr.input.NextInWindow(startTime, endTime) 7555 if err != nil { 7556 return nil, err 7557 } else if curr == nil { 7558 break 7559 } else if curr.Nil { 7560 continue 7561 } else if curr.Name != window.name { 7562 itr.input.unread(curr) 7563 break 7564 } 7565 7566 // Ensure this point is within the same final window. 7567 if curr.Name != window.name { 7568 itr.input.unread(curr) 7569 break 7570 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 7571 itr.input.unread(curr) 7572 break 7573 } 7574 7575 // Retrieve the tags on this point for this level of the query. 7576 // This may be different than the bucket dimensions. 7577 tags := curr.Tags.Subset(itr.dims) 7578 id := tags.ID() 7579 7580 // Retrieve the aggregator for this name/tag combination or create one. 7581 rp := m[id] 7582 if rp == nil { 7583 aggregator, emitter := itr.create() 7584 rp = &unsignedReduceBooleanPoint{ 7585 Name: curr.Name, 7586 Tags: tags, 7587 Aggregator: aggregator, 7588 Emitter: emitter, 7589 } 7590 m[id] = rp 7591 } 7592 rp.Aggregator.AggregateUnsigned(curr) 7593 } 7594 7595 keys := make([]string, 0, len(m)) 7596 for k := range m { 7597 keys = append(keys, k) 7598 } 7599 7600 // Reverse sort points by name & tag. 7601 // This ensures a consistent order of output. 7602 if len(keys) > 0 { 7603 var sorted sort.Interface = sort.StringSlice(keys) 7604 if itr.opt.Ascending { 7605 sorted = sort.Reverse(sorted) 7606 } 7607 sort.Sort(sorted) 7608 } 7609 7610 // Assume the points are already sorted until proven otherwise. 7611 sortedByTime := true 7612 // Emit the points for each name & tag combination. 7613 a := make([]BooleanPoint, 0, len(m)) 7614 for _, k := range keys { 7615 rp := m[k] 7616 points := rp.Emitter.Emit() 7617 for i := len(points) - 1; i >= 0; i-- { 7618 points[i].Name = rp.Name 7619 if !itr.keepTags { 7620 points[i].Tags = rp.Tags 7621 } 7622 // Set the points time to the interval time if the reducer didn't provide one. 7623 if points[i].Time == ZeroTime { 7624 points[i].Time = startTime 7625 } else { 7626 sortedByTime = false 7627 } 7628 a = append(a, points[i]) 7629 } 7630 } 7631 // Points may be out of order. Perform a stable sort by time if requested. 7632 if !sortedByTime && itr.opt.Ordered { 7633 var sorted sort.Interface = booleanPointsByTime(a) 7634 if itr.opt.Ascending { 7635 sorted = sort.Reverse(sorted) 7636 } 7637 sort.Stable(sorted) 7638 } 7639 return a, nil 7640 } 7641 7642 // unsignedStreamBooleanIterator streams inputs into the iterator and emits points gradually. 7643 type unsignedStreamBooleanIterator struct { 7644 input *bufUnsignedIterator 7645 create func() (UnsignedPointAggregator, BooleanPointEmitter) 7646 dims []string 7647 opt IteratorOptions 7648 m map[string]*unsignedReduceBooleanPoint 7649 points []BooleanPoint 7650 } 7651 7652 // newUnsignedStreamBooleanIterator returns a new instance of unsignedStreamBooleanIterator. 7653 func newUnsignedStreamBooleanIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, BooleanPointEmitter), opt IteratorOptions) *unsignedStreamBooleanIterator { 7654 return &unsignedStreamBooleanIterator{ 7655 input: newBufUnsignedIterator(input), 7656 create: createFn, 7657 dims: opt.GetDimensions(), 7658 opt: opt, 7659 m: make(map[string]*unsignedReduceBooleanPoint), 7660 } 7661 } 7662 7663 // Stats returns stats from the input iterator. 7664 func (itr *unsignedStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() } 7665 7666 // Close closes the iterator and all child iterators. 7667 func (itr *unsignedStreamBooleanIterator) Close() error { return itr.input.Close() } 7668 7669 // Next returns the next value for the stream iterator. 7670 func (itr *unsignedStreamBooleanIterator) Next() (*BooleanPoint, error) { 7671 // Calculate next window if we have no more points. 7672 if len(itr.points) == 0 { 7673 var err error 7674 itr.points, err = itr.reduce() 7675 if len(itr.points) == 0 { 7676 return nil, err 7677 } 7678 } 7679 7680 // Pop next point off the stack. 7681 p := &itr.points[len(itr.points)-1] 7682 itr.points = itr.points[:len(itr.points)-1] 7683 return p, nil 7684 } 7685 7686 // reduce creates and manages aggregators for every point from the input. 7687 // After aggregating a point, it always tries to emit a value using the emitter. 7688 func (itr *unsignedStreamBooleanIterator) reduce() ([]BooleanPoint, error) { 7689 // We have already read all of the input points. 7690 if itr.m == nil { 7691 return nil, nil 7692 } 7693 7694 for { 7695 // Read next point. 7696 curr, err := itr.input.Next() 7697 if err != nil { 7698 return nil, err 7699 } else if curr == nil { 7700 // Close all of the aggregators to flush any remaining points to emit. 7701 var points []BooleanPoint 7702 for _, rp := range itr.m { 7703 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 7704 if err := aggregator.Close(); err != nil { 7705 return nil, err 7706 } 7707 7708 pts := rp.Emitter.Emit() 7709 if len(pts) == 0 { 7710 continue 7711 } 7712 7713 for i := range pts { 7714 pts[i].Name = rp.Name 7715 pts[i].Tags = rp.Tags 7716 } 7717 points = append(points, pts...) 7718 } 7719 } 7720 7721 // Eliminate the aggregators and emitters. 7722 itr.m = nil 7723 return points, nil 7724 } else if curr.Nil { 7725 continue 7726 } 7727 tags := curr.Tags.Subset(itr.dims) 7728 7729 id := curr.Name 7730 if len(tags.m) > 0 { 7731 id += "\x00" + tags.ID() 7732 } 7733 7734 // Retrieve the aggregator for this name/tag combination or create one. 7735 rp := itr.m[id] 7736 if rp == nil { 7737 aggregator, emitter := itr.create() 7738 rp = &unsignedReduceBooleanPoint{ 7739 Name: curr.Name, 7740 Tags: tags, 7741 Aggregator: aggregator, 7742 Emitter: emitter, 7743 } 7744 itr.m[id] = rp 7745 } 7746 rp.Aggregator.AggregateUnsigned(curr) 7747 7748 // Attempt to emit points from the aggregator. 7749 points := rp.Emitter.Emit() 7750 if len(points) == 0 { 7751 continue 7752 } 7753 7754 for i := range points { 7755 points[i].Name = rp.Name 7756 points[i].Tags = rp.Tags 7757 } 7758 return points, nil 7759 } 7760 } 7761 7762 // unsignedDedupeIterator only outputs unique points. 7763 // This differs from the DistinctIterator in that it compares all aux fields too. 7764 // This iterator is relatively inefficient and should only be used on small 7765 // datasets such as meta query results. 7766 type unsignedDedupeIterator struct { 7767 input UnsignedIterator 7768 m map[string]struct{} // lookup of points already sent 7769 } 7770 7771 type unsignedIteratorMapper struct { 7772 cur Cursor 7773 row Row 7774 driver IteratorMap // which iterator to use for the primary value, can be nil 7775 fields []IteratorMap // which iterator to use for an aux field 7776 point UnsignedPoint 7777 } 7778 7779 func newUnsignedIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *unsignedIteratorMapper { 7780 return &unsignedIteratorMapper{ 7781 cur: cur, 7782 driver: driver, 7783 fields: fields, 7784 point: UnsignedPoint{ 7785 Aux: make([]interface{}, len(fields)), 7786 }, 7787 } 7788 } 7789 7790 func (itr *unsignedIteratorMapper) Next() (*UnsignedPoint, error) { 7791 if !itr.cur.Scan(&itr.row) { 7792 if err := itr.cur.Err(); err != nil { 7793 return nil, err 7794 } 7795 return nil, nil 7796 } 7797 7798 itr.point.Time = itr.row.Time 7799 itr.point.Name = itr.row.Series.Name 7800 itr.point.Tags = itr.row.Series.Tags 7801 7802 if itr.driver != nil { 7803 if v := itr.driver.Value(&itr.row); v != nil { 7804 if v, ok := castToUnsigned(v); ok { 7805 itr.point.Value = v 7806 itr.point.Nil = false 7807 } else { 7808 itr.point.Value = 0 7809 itr.point.Nil = true 7810 } 7811 } else { 7812 itr.point.Value = 0 7813 itr.point.Nil = true 7814 } 7815 } 7816 for i, f := range itr.fields { 7817 itr.point.Aux[i] = f.Value(&itr.row) 7818 } 7819 return &itr.point, nil 7820 } 7821 7822 func (itr *unsignedIteratorMapper) Stats() IteratorStats { 7823 return itr.cur.Stats() 7824 } 7825 7826 func (itr *unsignedIteratorMapper) Close() error { 7827 return itr.cur.Close() 7828 } 7829 7830 type unsignedFilterIterator struct { 7831 input UnsignedIterator 7832 cond influxql.Expr 7833 opt IteratorOptions 7834 m map[string]interface{} 7835 } 7836 7837 func newUnsignedFilterIterator(input UnsignedIterator, cond influxql.Expr, opt IteratorOptions) UnsignedIterator { 7838 // Strip out time conditions from the WHERE clause. 7839 // TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct. 7840 n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node { 7841 switch n := n.(type) { 7842 case *influxql.BinaryExpr: 7843 if n.LHS.String() == "time" { 7844 return &influxql.BooleanLiteral{Val: true} 7845 } 7846 } 7847 return n 7848 }) 7849 7850 cond, _ = n.(influxql.Expr) 7851 if cond == nil { 7852 return input 7853 } else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val { 7854 return input 7855 } 7856 7857 return &unsignedFilterIterator{ 7858 input: input, 7859 cond: cond, 7860 opt: opt, 7861 m: make(map[string]interface{}), 7862 } 7863 } 7864 7865 func (itr *unsignedFilterIterator) Stats() IteratorStats { return itr.input.Stats() } 7866 func (itr *unsignedFilterIterator) Close() error { return itr.input.Close() } 7867 7868 func (itr *unsignedFilterIterator) Next() (*UnsignedPoint, error) { 7869 for { 7870 p, err := itr.input.Next() 7871 if err != nil || p == nil { 7872 return nil, err 7873 } 7874 7875 for i, ref := range itr.opt.Aux { 7876 itr.m[ref.Val] = p.Aux[i] 7877 } 7878 for k, v := range p.Tags.KeyValues() { 7879 itr.m[k] = v 7880 } 7881 7882 if !influxql.EvalBool(itr.cond, itr.m) { 7883 continue 7884 } 7885 return p, nil 7886 } 7887 } 7888 7889 type unsignedTagSubsetIterator struct { 7890 input UnsignedIterator 7891 point UnsignedPoint 7892 lastTags Tags 7893 dimensions []string 7894 } 7895 7896 func newUnsignedTagSubsetIterator(input UnsignedIterator, opt IteratorOptions) *unsignedTagSubsetIterator { 7897 return &unsignedTagSubsetIterator{ 7898 input: input, 7899 dimensions: opt.GetDimensions(), 7900 } 7901 } 7902 7903 func (itr *unsignedTagSubsetIterator) Next() (*UnsignedPoint, error) { 7904 p, err := itr.input.Next() 7905 if err != nil { 7906 return nil, err 7907 } else if p == nil { 7908 return nil, nil 7909 } 7910 7911 itr.point.Name = p.Name 7912 if !p.Tags.Equal(itr.lastTags) { 7913 itr.point.Tags = p.Tags.Subset(itr.dimensions) 7914 itr.lastTags = p.Tags 7915 } 7916 itr.point.Time = p.Time 7917 itr.point.Value = p.Value 7918 itr.point.Aux = p.Aux 7919 itr.point.Aggregated = p.Aggregated 7920 itr.point.Nil = p.Nil 7921 return &itr.point, nil 7922 } 7923 7924 func (itr *unsignedTagSubsetIterator) Stats() IteratorStats { 7925 return itr.input.Stats() 7926 } 7927 7928 func (itr *unsignedTagSubsetIterator) Close() error { 7929 return itr.input.Close() 7930 } 7931 7932 // newUnsignedDedupeIterator returns a new instance of unsignedDedupeIterator. 7933 func newUnsignedDedupeIterator(input UnsignedIterator) *unsignedDedupeIterator { 7934 return &unsignedDedupeIterator{ 7935 input: input, 7936 m: make(map[string]struct{}), 7937 } 7938 } 7939 7940 // Stats returns stats from the input iterator. 7941 func (itr *unsignedDedupeIterator) Stats() IteratorStats { return itr.input.Stats() } 7942 7943 // Close closes the iterator and all child iterators. 7944 func (itr *unsignedDedupeIterator) Close() error { return itr.input.Close() } 7945 7946 // Next returns the next unique point from the input iterator. 7947 func (itr *unsignedDedupeIterator) Next() (*UnsignedPoint, error) { 7948 for { 7949 // Read next point. 7950 p, err := itr.input.Next() 7951 if p == nil || err != nil { 7952 return nil, err 7953 } 7954 7955 // Serialize to bytes to store in lookup. 7956 buf, err := proto.Marshal(encodeUnsignedPoint(p)) 7957 if err != nil { 7958 return nil, err 7959 } 7960 7961 // If the point has already been output then move to the next point. 7962 if _, ok := itr.m[string(buf)]; ok { 7963 continue 7964 } 7965 7966 // Otherwise mark it as emitted and return point. 7967 itr.m[string(buf)] = struct{}{} 7968 return p, nil 7969 } 7970 } 7971 7972 // unsignedReaderIterator represents an iterator that streams from a reader. 7973 type unsignedReaderIterator struct { 7974 r io.Reader 7975 dec *UnsignedPointDecoder 7976 } 7977 7978 // newUnsignedReaderIterator returns a new instance of unsignedReaderIterator. 7979 func newUnsignedReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *unsignedReaderIterator { 7980 dec := NewUnsignedPointDecoder(ctx, r) 7981 dec.stats = stats 7982 7983 return &unsignedReaderIterator{ 7984 r: r, 7985 dec: dec, 7986 } 7987 } 7988 7989 // Stats returns stats about points processed. 7990 func (itr *unsignedReaderIterator) Stats() IteratorStats { return itr.dec.stats } 7991 7992 // Close closes the underlying reader, if applicable. 7993 func (itr *unsignedReaderIterator) Close() error { 7994 if r, ok := itr.r.(io.ReadCloser); ok { 7995 return r.Close() 7996 } 7997 return nil 7998 } 7999 8000 // Next returns the next point from the iterator. 8001 func (itr *unsignedReaderIterator) Next() (*UnsignedPoint, error) { 8002 // OPTIMIZE(benbjohnson): Reuse point on iterator. 8003 8004 // Unmarshal next point. 8005 p := &UnsignedPoint{} 8006 if err := itr.dec.DecodeUnsignedPoint(p); err == io.EOF { 8007 return nil, nil 8008 } else if err != nil { 8009 return nil, err 8010 } 8011 return p, nil 8012 } 8013 8014 // StringIterator represents a stream of string points. 8015 type StringIterator interface { 8016 Iterator 8017 Next() (*StringPoint, error) 8018 } 8019 8020 // newStringIterators converts a slice of Iterator to a slice of StringIterator. 8021 // Drop and closes any iterator in itrs that is not a StringIterator and cannot 8022 // be cast to a StringIterator. 8023 func newStringIterators(itrs []Iterator) []StringIterator { 8024 a := make([]StringIterator, 0, len(itrs)) 8025 for _, itr := range itrs { 8026 switch itr := itr.(type) { 8027 case StringIterator: 8028 a = append(a, itr) 8029 default: 8030 itr.Close() 8031 } 8032 } 8033 return a 8034 } 8035 8036 // bufStringIterator represents a buffered StringIterator. 8037 type bufStringIterator struct { 8038 itr StringIterator 8039 buf *StringPoint 8040 } 8041 8042 // newBufStringIterator returns a buffered StringIterator. 8043 func newBufStringIterator(itr StringIterator) *bufStringIterator { 8044 return &bufStringIterator{itr: itr} 8045 } 8046 8047 // Stats returns statistics from the input iterator. 8048 func (itr *bufStringIterator) Stats() IteratorStats { return itr.itr.Stats() } 8049 8050 // Close closes the underlying iterator. 8051 func (itr *bufStringIterator) Close() error { return itr.itr.Close() } 8052 8053 // peek returns the next point without removing it from the iterator. 8054 func (itr *bufStringIterator) peek() (*StringPoint, error) { 8055 p, err := itr.Next() 8056 if err != nil { 8057 return nil, err 8058 } 8059 itr.unread(p) 8060 return p, nil 8061 } 8062 8063 // peekTime returns the time of the next point. 8064 // Returns zero time if no more points available. 8065 func (itr *bufStringIterator) peekTime() (int64, error) { 8066 p, err := itr.peek() 8067 if p == nil || err != nil { 8068 return ZeroTime, err 8069 } 8070 return p.Time, nil 8071 } 8072 8073 // Next returns the current buffer, if exists, or calls the underlying iterator. 8074 func (itr *bufStringIterator) Next() (*StringPoint, error) { 8075 buf := itr.buf 8076 if buf != nil { 8077 itr.buf = nil 8078 return buf, nil 8079 } 8080 return itr.itr.Next() 8081 } 8082 8083 // NextInWindow returns the next value if it is between [startTime, endTime). 8084 // If the next value is outside the range then it is moved to the buffer. 8085 func (itr *bufStringIterator) NextInWindow(startTime, endTime int64) (*StringPoint, error) { 8086 v, err := itr.Next() 8087 if v == nil || err != nil { 8088 return nil, err 8089 } else if t := v.Time; t >= endTime || t < startTime { 8090 itr.unread(v) 8091 return nil, nil 8092 } 8093 return v, nil 8094 } 8095 8096 // unread sets v to the buffer. It is read on the next call to Next(). 8097 func (itr *bufStringIterator) unread(v *StringPoint) { itr.buf = v } 8098 8099 // stringMergeIterator represents an iterator that combines multiple string iterators. 8100 type stringMergeIterator struct { 8101 inputs []StringIterator 8102 heap *stringMergeHeap 8103 init bool 8104 8105 closed bool 8106 mu sync.RWMutex 8107 8108 // Current iterator and window. 8109 curr *stringMergeHeapItem 8110 window struct { 8111 name string 8112 tags string 8113 startTime int64 8114 endTime int64 8115 } 8116 } 8117 8118 // newStringMergeIterator returns a new instance of stringMergeIterator. 8119 func newStringMergeIterator(inputs []StringIterator, opt IteratorOptions) *stringMergeIterator { 8120 itr := &stringMergeIterator{ 8121 inputs: inputs, 8122 heap: &stringMergeHeap{ 8123 items: make([]*stringMergeHeapItem, 0, len(inputs)), 8124 opt: opt, 8125 }, 8126 } 8127 8128 // Initialize heap items. 8129 for _, input := range inputs { 8130 // Wrap in buffer, ignore any inputs without anymore points. 8131 bufInput := newBufStringIterator(input) 8132 8133 // Append to the heap. 8134 itr.heap.items = append(itr.heap.items, &stringMergeHeapItem{itr: bufInput}) 8135 } 8136 8137 return itr 8138 } 8139 8140 // Stats returns an aggregation of stats from the underlying iterators. 8141 func (itr *stringMergeIterator) Stats() IteratorStats { 8142 var stats IteratorStats 8143 for _, input := range itr.inputs { 8144 stats.Add(input.Stats()) 8145 } 8146 return stats 8147 } 8148 8149 // Close closes the underlying iterators. 8150 func (itr *stringMergeIterator) Close() error { 8151 itr.mu.Lock() 8152 defer itr.mu.Unlock() 8153 8154 for _, input := range itr.inputs { 8155 input.Close() 8156 } 8157 itr.curr = nil 8158 itr.inputs = nil 8159 itr.heap.items = nil 8160 itr.closed = true 8161 return nil 8162 } 8163 8164 // Next returns the next point from the iterator. 8165 func (itr *stringMergeIterator) Next() (*StringPoint, error) { 8166 itr.mu.RLock() 8167 defer itr.mu.RUnlock() 8168 if itr.closed { 8169 return nil, nil 8170 } 8171 8172 // Initialize the heap. This needs to be done lazily on the first call to this iterator 8173 // so that iterator initialization done through the Select() call returns quickly. 8174 // Queries can only be interrupted after the Select() call completes so any operations 8175 // done during iterator creation cannot be interrupted, which is why we do it here 8176 // instead so an interrupt can happen while initializing the heap. 8177 if !itr.init { 8178 items := itr.heap.items 8179 itr.heap.items = make([]*stringMergeHeapItem, 0, len(items)) 8180 for _, item := range items { 8181 if p, err := item.itr.peek(); err != nil { 8182 return nil, err 8183 } else if p == nil { 8184 continue 8185 } 8186 itr.heap.items = append(itr.heap.items, item) 8187 } 8188 heap.Init(itr.heap) 8189 itr.init = true 8190 } 8191 8192 for { 8193 // Retrieve the next iterator if we don't have one. 8194 if itr.curr == nil { 8195 if len(itr.heap.items) == 0 { 8196 return nil, nil 8197 } 8198 itr.curr = heap.Pop(itr.heap).(*stringMergeHeapItem) 8199 8200 // Read point and set current window. 8201 p, err := itr.curr.itr.Next() 8202 if err != nil { 8203 return nil, err 8204 } 8205 tags := p.Tags.Subset(itr.heap.opt.Dimensions) 8206 itr.window.name, itr.window.tags = p.Name, tags.ID() 8207 itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time) 8208 return p, nil 8209 } 8210 8211 // Read the next point from the current iterator. 8212 p, err := itr.curr.itr.Next() 8213 if err != nil { 8214 return nil, err 8215 } 8216 8217 // If there are no more points then remove iterator from heap and find next. 8218 if p == nil { 8219 itr.curr = nil 8220 continue 8221 } 8222 8223 // Check if the point is inside of our current window. 8224 inWindow := true 8225 if window := itr.window; window.name != p.Name { 8226 inWindow = false 8227 } else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() { 8228 inWindow = false 8229 } else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime { 8230 inWindow = false 8231 } else if !opt.Ascending && p.Time < window.startTime { 8232 inWindow = false 8233 } 8234 8235 // If it's outside our window then push iterator back on the heap and find new iterator. 8236 if !inWindow { 8237 itr.curr.itr.unread(p) 8238 heap.Push(itr.heap, itr.curr) 8239 itr.curr = nil 8240 continue 8241 } 8242 8243 return p, nil 8244 } 8245 } 8246 8247 // stringMergeHeap represents a heap of stringMergeHeapItems. 8248 // Items are sorted by their next window and then by name/tags. 8249 type stringMergeHeap struct { 8250 opt IteratorOptions 8251 items []*stringMergeHeapItem 8252 } 8253 8254 func (h *stringMergeHeap) Len() int { return len(h.items) } 8255 func (h *stringMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] } 8256 func (h *stringMergeHeap) Less(i, j int) bool { 8257 x, err := h.items[i].itr.peek() 8258 if err != nil { 8259 return true 8260 } 8261 y, err := h.items[j].itr.peek() 8262 if err != nil { 8263 return false 8264 } 8265 8266 if h.opt.Ascending { 8267 if x.Name != y.Name { 8268 return x.Name < y.Name 8269 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() { 8270 return xTags.ID() < yTags.ID() 8271 } 8272 } else { 8273 if x.Name != y.Name { 8274 return x.Name > y.Name 8275 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() { 8276 return xTags.ID() > yTags.ID() 8277 } 8278 } 8279 8280 xt, _ := h.opt.Window(x.Time) 8281 yt, _ := h.opt.Window(y.Time) 8282 8283 if h.opt.Ascending { 8284 return xt < yt 8285 } 8286 return xt > yt 8287 } 8288 8289 func (h *stringMergeHeap) Push(x interface{}) { 8290 h.items = append(h.items, x.(*stringMergeHeapItem)) 8291 } 8292 8293 func (h *stringMergeHeap) Pop() interface{} { 8294 old := h.items 8295 n := len(old) 8296 item := old[n-1] 8297 h.items = old[0 : n-1] 8298 return item 8299 } 8300 8301 type stringMergeHeapItem struct { 8302 itr *bufStringIterator 8303 } 8304 8305 // stringSortedMergeIterator is an iterator that sorts and merges multiple iterators into one. 8306 type stringSortedMergeIterator struct { 8307 inputs []StringIterator 8308 heap *stringSortedMergeHeap 8309 init bool 8310 } 8311 8312 // newStringSortedMergeIterator returns an instance of stringSortedMergeIterator. 8313 func newStringSortedMergeIterator(inputs []StringIterator, opt IteratorOptions) Iterator { 8314 itr := &stringSortedMergeIterator{ 8315 inputs: inputs, 8316 heap: &stringSortedMergeHeap{ 8317 items: make([]*stringSortedMergeHeapItem, 0, len(inputs)), 8318 opt: opt, 8319 }, 8320 } 8321 8322 // Initialize heap items. 8323 for _, input := range inputs { 8324 // Append to the heap. 8325 itr.heap.items = append(itr.heap.items, &stringSortedMergeHeapItem{itr: input}) 8326 } 8327 8328 return itr 8329 } 8330 8331 // Stats returns an aggregation of stats from the underlying iterators. 8332 func (itr *stringSortedMergeIterator) Stats() IteratorStats { 8333 var stats IteratorStats 8334 for _, input := range itr.inputs { 8335 stats.Add(input.Stats()) 8336 } 8337 return stats 8338 } 8339 8340 // Close closes the underlying iterators. 8341 func (itr *stringSortedMergeIterator) Close() error { 8342 for _, input := range itr.inputs { 8343 input.Close() 8344 } 8345 return nil 8346 } 8347 8348 // Next returns the next points from the iterator. 8349 func (itr *stringSortedMergeIterator) Next() (*StringPoint, error) { return itr.pop() } 8350 8351 // pop returns the next point from the heap. 8352 // Reads the next point from item's cursor and puts it back on the heap. 8353 func (itr *stringSortedMergeIterator) pop() (*StringPoint, error) { 8354 // Initialize the heap. See the MergeIterator to see why this has to be done lazily. 8355 if !itr.init { 8356 items := itr.heap.items 8357 itr.heap.items = make([]*stringSortedMergeHeapItem, 0, len(items)) 8358 for _, item := range items { 8359 var err error 8360 if item.point, err = item.itr.Next(); err != nil { 8361 return nil, err 8362 } else if item.point == nil { 8363 continue 8364 } 8365 itr.heap.items = append(itr.heap.items, item) 8366 } 8367 heap.Init(itr.heap) 8368 itr.init = true 8369 } 8370 8371 if len(itr.heap.items) == 0 { 8372 return nil, nil 8373 } 8374 8375 // Read the next item from the heap. 8376 item := heap.Pop(itr.heap).(*stringSortedMergeHeapItem) 8377 if item.err != nil { 8378 return nil, item.err 8379 } else if item.point == nil { 8380 return nil, nil 8381 } 8382 8383 // Copy the point for return. 8384 p := item.point.Clone() 8385 8386 // Read the next item from the cursor. Push back to heap if one exists. 8387 if item.point, item.err = item.itr.Next(); item.point != nil { 8388 heap.Push(itr.heap, item) 8389 } 8390 8391 return p, nil 8392 } 8393 8394 // stringSortedMergeHeap represents a heap of stringSortedMergeHeapItems. 8395 // Items are sorted with the following priority: 8396 // - By their measurement name; 8397 // - By their tag keys/values; 8398 // - By time; or 8399 // - By their Aux field values. 8400 type stringSortedMergeHeap struct { 8401 opt IteratorOptions 8402 items []*stringSortedMergeHeapItem 8403 } 8404 8405 func (h *stringSortedMergeHeap) Len() int { return len(h.items) } 8406 func (h *stringSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] } 8407 func (h *stringSortedMergeHeap) Less(i, j int) bool { 8408 x, y := h.items[i].point, h.items[j].point 8409 8410 if h.opt.Ascending { 8411 if x.Name != y.Name { 8412 return x.Name < y.Name 8413 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) { 8414 return xTags.ID() < yTags.ID() 8415 } 8416 8417 if x.Time != y.Time { 8418 return x.Time < y.Time 8419 } 8420 8421 if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) { 8422 for i := 0; i < len(x.Aux); i++ { 8423 v1, ok1 := x.Aux[i].(string) 8424 v2, ok2 := y.Aux[i].(string) 8425 if !ok1 || !ok2 { 8426 // Unsupported types used in Aux fields. Maybe they 8427 // need to be added here? 8428 return false 8429 } else if v1 == v2 { 8430 continue 8431 } 8432 return v1 < v2 8433 } 8434 } 8435 return false // Times and/or Aux fields are equal. 8436 } 8437 8438 if x.Name != y.Name { 8439 return x.Name > y.Name 8440 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) { 8441 return xTags.ID() > yTags.ID() 8442 } 8443 8444 if x.Time != y.Time { 8445 return x.Time > y.Time 8446 } 8447 8448 if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) { 8449 for i := 0; i < len(x.Aux); i++ { 8450 v1, ok1 := x.Aux[i].(string) 8451 v2, ok2 := y.Aux[i].(string) 8452 if !ok1 || !ok2 { 8453 // Unsupported types used in Aux fields. Maybe they 8454 // need to be added here? 8455 return false 8456 } else if v1 == v2 { 8457 continue 8458 } 8459 return v1 > v2 8460 } 8461 } 8462 return false // Times and/or Aux fields are equal. 8463 } 8464 8465 func (h *stringSortedMergeHeap) Push(x interface{}) { 8466 h.items = append(h.items, x.(*stringSortedMergeHeapItem)) 8467 } 8468 8469 func (h *stringSortedMergeHeap) Pop() interface{} { 8470 old := h.items 8471 n := len(old) 8472 item := old[n-1] 8473 h.items = old[0 : n-1] 8474 return item 8475 } 8476 8477 type stringSortedMergeHeapItem struct { 8478 point *StringPoint 8479 err error 8480 itr StringIterator 8481 } 8482 8483 // stringIteratorScanner scans the results of a StringIterator into a map. 8484 type stringIteratorScanner struct { 8485 input *bufStringIterator 8486 err error 8487 keys []influxql.VarRef 8488 defaultValue interface{} 8489 } 8490 8491 // newStringIteratorScanner creates a new IteratorScanner. 8492 func newStringIteratorScanner(input StringIterator, keys []influxql.VarRef, defaultValue interface{}) *stringIteratorScanner { 8493 return &stringIteratorScanner{ 8494 input: newBufStringIterator(input), 8495 keys: keys, 8496 defaultValue: defaultValue, 8497 } 8498 } 8499 8500 func (s *stringIteratorScanner) Peek() (int64, string, Tags) { 8501 if s.err != nil { 8502 return ZeroTime, "", Tags{} 8503 } 8504 8505 p, err := s.input.peek() 8506 if err != nil { 8507 s.err = err 8508 return ZeroTime, "", Tags{} 8509 } else if p == nil { 8510 return ZeroTime, "", Tags{} 8511 } 8512 return p.Time, p.Name, p.Tags 8513 } 8514 8515 func (s *stringIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) { 8516 if s.err != nil { 8517 return 8518 } 8519 8520 p, err := s.input.Next() 8521 if err != nil { 8522 s.err = err 8523 return 8524 } else if p == nil { 8525 s.useDefaults(m) 8526 return 8527 } else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) { 8528 s.useDefaults(m) 8529 s.input.unread(p) 8530 return 8531 } 8532 8533 if k := s.keys[0]; k.Val != "" { 8534 if p.Nil { 8535 if s.defaultValue != SkipDefault { 8536 m[k.Val] = castToType(s.defaultValue, k.Type) 8537 } 8538 } else { 8539 m[k.Val] = p.Value 8540 } 8541 } 8542 for i, v := range p.Aux { 8543 k := s.keys[i+1] 8544 switch v.(type) { 8545 case float64, int64, uint64, string, bool: 8546 m[k.Val] = v 8547 default: 8548 // Insert the fill value if one was specified. 8549 if s.defaultValue != SkipDefault { 8550 m[k.Val] = castToType(s.defaultValue, k.Type) 8551 } 8552 } 8553 } 8554 } 8555 8556 func (s *stringIteratorScanner) useDefaults(m map[string]interface{}) { 8557 if s.defaultValue == SkipDefault { 8558 return 8559 } 8560 for _, k := range s.keys { 8561 if k.Val == "" { 8562 continue 8563 } 8564 m[k.Val] = castToType(s.defaultValue, k.Type) 8565 } 8566 } 8567 8568 func (s *stringIteratorScanner) Stats() IteratorStats { return s.input.Stats() } 8569 func (s *stringIteratorScanner) Err() error { return s.err } 8570 func (s *stringIteratorScanner) Close() error { return s.input.Close() } 8571 8572 // stringParallelIterator represents an iterator that pulls data in a separate goroutine. 8573 type stringParallelIterator struct { 8574 input StringIterator 8575 ch chan stringPointError 8576 8577 once sync.Once 8578 closing chan struct{} 8579 wg sync.WaitGroup 8580 } 8581 8582 // newStringParallelIterator returns a new instance of stringParallelIterator. 8583 func newStringParallelIterator(input StringIterator) *stringParallelIterator { 8584 itr := &stringParallelIterator{ 8585 input: input, 8586 ch: make(chan stringPointError, 256), 8587 closing: make(chan struct{}), 8588 } 8589 itr.wg.Add(1) 8590 go itr.monitor() 8591 return itr 8592 } 8593 8594 // Stats returns stats from the underlying iterator. 8595 func (itr *stringParallelIterator) Stats() IteratorStats { return itr.input.Stats() } 8596 8597 // Close closes the underlying iterators. 8598 func (itr *stringParallelIterator) Close() error { 8599 itr.once.Do(func() { close(itr.closing) }) 8600 itr.wg.Wait() 8601 return itr.input.Close() 8602 } 8603 8604 // Next returns the next point from the iterator. 8605 func (itr *stringParallelIterator) Next() (*StringPoint, error) { 8606 v, ok := <-itr.ch 8607 if !ok { 8608 return nil, io.EOF 8609 } 8610 return v.point, v.err 8611 } 8612 8613 // monitor runs in a separate goroutine and actively pulls the next point. 8614 func (itr *stringParallelIterator) monitor() { 8615 defer close(itr.ch) 8616 defer itr.wg.Done() 8617 8618 for { 8619 // Read next point. 8620 p, err := itr.input.Next() 8621 if p != nil { 8622 p = p.Clone() 8623 } 8624 8625 select { 8626 case <-itr.closing: 8627 return 8628 case itr.ch <- stringPointError{point: p, err: err}: 8629 } 8630 } 8631 } 8632 8633 type stringPointError struct { 8634 point *StringPoint 8635 err error 8636 } 8637 8638 // stringLimitIterator represents an iterator that limits points per group. 8639 type stringLimitIterator struct { 8640 input StringIterator 8641 opt IteratorOptions 8642 n int 8643 8644 prev struct { 8645 name string 8646 tags Tags 8647 } 8648 } 8649 8650 // newStringLimitIterator returns a new instance of stringLimitIterator. 8651 func newStringLimitIterator(input StringIterator, opt IteratorOptions) *stringLimitIterator { 8652 return &stringLimitIterator{ 8653 input: input, 8654 opt: opt, 8655 } 8656 } 8657 8658 // Stats returns stats from the underlying iterator. 8659 func (itr *stringLimitIterator) Stats() IteratorStats { return itr.input.Stats() } 8660 8661 // Close closes the underlying iterators. 8662 func (itr *stringLimitIterator) Close() error { return itr.input.Close() } 8663 8664 // Next returns the next point from the iterator. 8665 func (itr *stringLimitIterator) Next() (*StringPoint, error) { 8666 for { 8667 p, err := itr.input.Next() 8668 if p == nil || err != nil { 8669 return nil, err 8670 } 8671 8672 // Reset window and counter if a new window is encountered. 8673 if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) { 8674 itr.prev.name = p.Name 8675 itr.prev.tags = p.Tags 8676 itr.n = 0 8677 } 8678 8679 // Increment counter. 8680 itr.n++ 8681 8682 // Read next point if not beyond the offset. 8683 if itr.n <= itr.opt.Offset { 8684 continue 8685 } 8686 8687 // Read next point if we're beyond the limit. 8688 if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit { 8689 continue 8690 } 8691 8692 return p, nil 8693 } 8694 } 8695 8696 type stringFillIterator struct { 8697 input *bufStringIterator 8698 prev StringPoint 8699 startTime int64 8700 endTime int64 8701 auxFields []interface{} 8702 init bool 8703 opt IteratorOptions 8704 8705 window struct { 8706 name string 8707 tags Tags 8708 time int64 8709 offset int64 8710 } 8711 } 8712 8713 func newStringFillIterator(input StringIterator, expr influxql.Expr, opt IteratorOptions) *stringFillIterator { 8714 if opt.Fill == influxql.NullFill { 8715 if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" { 8716 opt.Fill = influxql.NumberFill 8717 opt.FillValue = "" 8718 } 8719 } 8720 8721 var startTime, endTime int64 8722 if opt.Ascending { 8723 startTime, _ = opt.Window(opt.StartTime) 8724 endTime, _ = opt.Window(opt.EndTime) 8725 } else { 8726 startTime, _ = opt.Window(opt.EndTime) 8727 endTime, _ = opt.Window(opt.StartTime) 8728 } 8729 8730 var auxFields []interface{} 8731 if len(opt.Aux) > 0 { 8732 auxFields = make([]interface{}, len(opt.Aux)) 8733 } 8734 8735 return &stringFillIterator{ 8736 input: newBufStringIterator(input), 8737 prev: StringPoint{Nil: true}, 8738 startTime: startTime, 8739 endTime: endTime, 8740 auxFields: auxFields, 8741 opt: opt, 8742 } 8743 } 8744 8745 func (itr *stringFillIterator) Stats() IteratorStats { return itr.input.Stats() } 8746 func (itr *stringFillIterator) Close() error { return itr.input.Close() } 8747 8748 func (itr *stringFillIterator) Next() (*StringPoint, error) { 8749 if !itr.init { 8750 p, err := itr.input.peek() 8751 if p == nil || err != nil { 8752 return nil, err 8753 } 8754 itr.window.name, itr.window.tags = p.Name, p.Tags 8755 itr.window.time = itr.startTime 8756 if itr.startTime == influxql.MinTime { 8757 itr.window.time, _ = itr.opt.Window(p.Time) 8758 } 8759 if itr.opt.Location != nil { 8760 _, itr.window.offset = itr.opt.Zone(itr.window.time) 8761 } 8762 itr.init = true 8763 } 8764 8765 p, err := itr.input.Next() 8766 if err != nil { 8767 return nil, err 8768 } 8769 8770 // Check if the next point is outside of our window or is nil. 8771 if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() { 8772 // If we are inside of an interval, unread the point and continue below to 8773 // constructing a new point. 8774 if itr.opt.Ascending && itr.window.time <= itr.endTime { 8775 itr.input.unread(p) 8776 p = nil 8777 goto CONSTRUCT 8778 } else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime { 8779 itr.input.unread(p) 8780 p = nil 8781 goto CONSTRUCT 8782 } 8783 8784 // We are *not* in a current interval. If there is no next point, 8785 // we are at the end of all intervals. 8786 if p == nil { 8787 return nil, nil 8788 } 8789 8790 // Set the new interval. 8791 itr.window.name, itr.window.tags = p.Name, p.Tags 8792 itr.window.time = itr.startTime 8793 if itr.window.time == influxql.MinTime { 8794 itr.window.time, _ = itr.opt.Window(p.Time) 8795 } 8796 if itr.opt.Location != nil { 8797 _, itr.window.offset = itr.opt.Zone(itr.window.time) 8798 } 8799 itr.prev = StringPoint{Nil: true} 8800 } 8801 8802 // Check if the point is our next expected point. 8803 CONSTRUCT: 8804 if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) { 8805 if p != nil { 8806 itr.input.unread(p) 8807 } 8808 8809 p = &StringPoint{ 8810 Name: itr.window.name, 8811 Tags: itr.window.tags, 8812 Time: itr.window.time, 8813 Aux: itr.auxFields, 8814 } 8815 8816 switch itr.opt.Fill { 8817 case influxql.LinearFill: 8818 fallthrough 8819 case influxql.NullFill: 8820 p.Nil = true 8821 case influxql.NumberFill: 8822 p.Value, _ = castToString(itr.opt.FillValue) 8823 case influxql.PreviousFill: 8824 if !itr.prev.Nil { 8825 p.Value = itr.prev.Value 8826 p.Nil = itr.prev.Nil 8827 } else { 8828 p.Nil = true 8829 } 8830 } 8831 } else { 8832 itr.prev = *p 8833 } 8834 8835 // Advance the expected time. Do not advance to a new window here 8836 // as there may be lingering points with the same timestamp in the previous 8837 // window. 8838 if itr.opt.Ascending { 8839 itr.window.time += int64(itr.opt.Interval.Duration) 8840 } else { 8841 itr.window.time -= int64(itr.opt.Interval.Duration) 8842 } 8843 8844 // Check to see if we have passed over an offset change and adjust the time 8845 // to account for this new offset. 8846 if itr.opt.Location != nil { 8847 if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset { 8848 diff := itr.window.offset - offset 8849 if abs(diff) < int64(itr.opt.Interval.Duration) { 8850 itr.window.time += diff 8851 } 8852 itr.window.offset = offset 8853 } 8854 } 8855 return p, nil 8856 } 8857 8858 // stringIntervalIterator represents a string implementation of IntervalIterator. 8859 type stringIntervalIterator struct { 8860 input StringIterator 8861 opt IteratorOptions 8862 } 8863 8864 func newStringIntervalIterator(input StringIterator, opt IteratorOptions) *stringIntervalIterator { 8865 return &stringIntervalIterator{input: input, opt: opt} 8866 } 8867 8868 func (itr *stringIntervalIterator) Stats() IteratorStats { return itr.input.Stats() } 8869 func (itr *stringIntervalIterator) Close() error { return itr.input.Close() } 8870 8871 func (itr *stringIntervalIterator) Next() (*StringPoint, error) { 8872 p, err := itr.input.Next() 8873 if p == nil || err != nil { 8874 return nil, err 8875 } 8876 p.Time, _ = itr.opt.Window(p.Time) 8877 // If we see the minimum allowable time, set the time to zero so we don't 8878 // break the default returned time for aggregate queries without times. 8879 if p.Time == influxql.MinTime { 8880 p.Time = 0 8881 } 8882 return p, nil 8883 } 8884 8885 // stringInterruptIterator represents a string implementation of InterruptIterator. 8886 type stringInterruptIterator struct { 8887 input StringIterator 8888 closing <-chan struct{} 8889 count int 8890 } 8891 8892 func newStringInterruptIterator(input StringIterator, closing <-chan struct{}) *stringInterruptIterator { 8893 return &stringInterruptIterator{input: input, closing: closing} 8894 } 8895 8896 func (itr *stringInterruptIterator) Stats() IteratorStats { return itr.input.Stats() } 8897 func (itr *stringInterruptIterator) Close() error { return itr.input.Close() } 8898 8899 func (itr *stringInterruptIterator) Next() (*StringPoint, error) { 8900 // Only check if the channel is closed every N points. This 8901 // intentionally checks on both 0 and N so that if the iterator 8902 // has been interrupted before the first point is emitted it will 8903 // not emit any points. 8904 if itr.count&0xFF == 0xFF { 8905 select { 8906 case <-itr.closing: 8907 return nil, itr.Close() 8908 default: 8909 // Reset iterator count to zero and fall through to emit the next point. 8910 itr.count = 0 8911 } 8912 } 8913 8914 // Increment the counter for every point read. 8915 itr.count++ 8916 return itr.input.Next() 8917 } 8918 8919 // stringCloseInterruptIterator represents a string implementation of CloseInterruptIterator. 8920 type stringCloseInterruptIterator struct { 8921 input StringIterator 8922 closing <-chan struct{} 8923 done chan struct{} 8924 once sync.Once 8925 } 8926 8927 func newStringCloseInterruptIterator(input StringIterator, closing <-chan struct{}) *stringCloseInterruptIterator { 8928 itr := &stringCloseInterruptIterator{ 8929 input: input, 8930 closing: closing, 8931 done: make(chan struct{}), 8932 } 8933 go itr.monitor() 8934 return itr 8935 } 8936 8937 func (itr *stringCloseInterruptIterator) monitor() { 8938 select { 8939 case <-itr.closing: 8940 itr.Close() 8941 case <-itr.done: 8942 } 8943 } 8944 8945 func (itr *stringCloseInterruptIterator) Stats() IteratorStats { 8946 return itr.input.Stats() 8947 } 8948 8949 func (itr *stringCloseInterruptIterator) Close() error { 8950 itr.once.Do(func() { 8951 close(itr.done) 8952 itr.input.Close() 8953 }) 8954 return nil 8955 } 8956 8957 func (itr *stringCloseInterruptIterator) Next() (*StringPoint, error) { 8958 p, err := itr.input.Next() 8959 if err != nil { 8960 // Check if the iterator was closed. 8961 select { 8962 case <-itr.done: 8963 return nil, nil 8964 default: 8965 return nil, err 8966 } 8967 } 8968 return p, nil 8969 } 8970 8971 // stringReduceFloatIterator executes a reducer for every interval and buffers the result. 8972 type stringReduceFloatIterator struct { 8973 input *bufStringIterator 8974 create func() (StringPointAggregator, FloatPointEmitter) 8975 dims []string 8976 opt IteratorOptions 8977 points []FloatPoint 8978 keepTags bool 8979 } 8980 8981 func newStringReduceFloatIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, FloatPointEmitter)) *stringReduceFloatIterator { 8982 return &stringReduceFloatIterator{ 8983 input: newBufStringIterator(input), 8984 create: createFn, 8985 dims: opt.GetDimensions(), 8986 opt: opt, 8987 } 8988 } 8989 8990 // Stats returns stats from the input iterator. 8991 func (itr *stringReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() } 8992 8993 // Close closes the iterator and all child iterators. 8994 func (itr *stringReduceFloatIterator) Close() error { return itr.input.Close() } 8995 8996 // Next returns the minimum value for the next available interval. 8997 func (itr *stringReduceFloatIterator) Next() (*FloatPoint, error) { 8998 // Calculate next window if we have no more points. 8999 if len(itr.points) == 0 { 9000 var err error 9001 itr.points, err = itr.reduce() 9002 if len(itr.points) == 0 { 9003 return nil, err 9004 } 9005 } 9006 9007 // Pop next point off the stack. 9008 p := &itr.points[len(itr.points)-1] 9009 itr.points = itr.points[:len(itr.points)-1] 9010 return p, nil 9011 } 9012 9013 // stringReduceFloatPoint stores the reduced data for a name/tag combination. 9014 type stringReduceFloatPoint struct { 9015 Name string 9016 Tags Tags 9017 Aggregator StringPointAggregator 9018 Emitter FloatPointEmitter 9019 } 9020 9021 // reduce executes fn once for every point in the next window. 9022 // The previous value for the dimension is passed to fn. 9023 func (itr *stringReduceFloatIterator) reduce() ([]FloatPoint, error) { 9024 // Calculate next window. 9025 var ( 9026 startTime, endTime int64 9027 window struct { 9028 name string 9029 tags string 9030 } 9031 ) 9032 for { 9033 p, err := itr.input.Next() 9034 if err != nil || p == nil { 9035 return nil, err 9036 } else if p.Nil { 9037 continue 9038 } 9039 9040 // Unread the point so it can be processed. 9041 itr.input.unread(p) 9042 startTime, endTime = itr.opt.Window(p.Time) 9043 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 9044 break 9045 } 9046 9047 // Create points by tags. 9048 m := make(map[string]*stringReduceFloatPoint) 9049 for { 9050 // Read next point. 9051 curr, err := itr.input.NextInWindow(startTime, endTime) 9052 if err != nil { 9053 return nil, err 9054 } else if curr == nil { 9055 break 9056 } else if curr.Nil { 9057 continue 9058 } else if curr.Name != window.name { 9059 itr.input.unread(curr) 9060 break 9061 } 9062 9063 // Ensure this point is within the same final window. 9064 if curr.Name != window.name { 9065 itr.input.unread(curr) 9066 break 9067 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 9068 itr.input.unread(curr) 9069 break 9070 } 9071 9072 // Retrieve the tags on this point for this level of the query. 9073 // This may be different than the bucket dimensions. 9074 tags := curr.Tags.Subset(itr.dims) 9075 id := tags.ID() 9076 9077 // Retrieve the aggregator for this name/tag combination or create one. 9078 rp := m[id] 9079 if rp == nil { 9080 aggregator, emitter := itr.create() 9081 rp = &stringReduceFloatPoint{ 9082 Name: curr.Name, 9083 Tags: tags, 9084 Aggregator: aggregator, 9085 Emitter: emitter, 9086 } 9087 m[id] = rp 9088 } 9089 rp.Aggregator.AggregateString(curr) 9090 } 9091 9092 keys := make([]string, 0, len(m)) 9093 for k := range m { 9094 keys = append(keys, k) 9095 } 9096 9097 // Reverse sort points by name & tag. 9098 // This ensures a consistent order of output. 9099 if len(keys) > 0 { 9100 var sorted sort.Interface = sort.StringSlice(keys) 9101 if itr.opt.Ascending { 9102 sorted = sort.Reverse(sorted) 9103 } 9104 sort.Sort(sorted) 9105 } 9106 9107 // Assume the points are already sorted until proven otherwise. 9108 sortedByTime := true 9109 // Emit the points for each name & tag combination. 9110 a := make([]FloatPoint, 0, len(m)) 9111 for _, k := range keys { 9112 rp := m[k] 9113 points := rp.Emitter.Emit() 9114 for i := len(points) - 1; i >= 0; i-- { 9115 points[i].Name = rp.Name 9116 if !itr.keepTags { 9117 points[i].Tags = rp.Tags 9118 } 9119 // Set the points time to the interval time if the reducer didn't provide one. 9120 if points[i].Time == ZeroTime { 9121 points[i].Time = startTime 9122 } else { 9123 sortedByTime = false 9124 } 9125 a = append(a, points[i]) 9126 } 9127 } 9128 // Points may be out of order. Perform a stable sort by time if requested. 9129 if !sortedByTime && itr.opt.Ordered { 9130 var sorted sort.Interface = floatPointsByTime(a) 9131 if itr.opt.Ascending { 9132 sorted = sort.Reverse(sorted) 9133 } 9134 sort.Stable(sorted) 9135 } 9136 return a, nil 9137 } 9138 9139 // stringStreamFloatIterator streams inputs into the iterator and emits points gradually. 9140 type stringStreamFloatIterator struct { 9141 input *bufStringIterator 9142 create func() (StringPointAggregator, FloatPointEmitter) 9143 dims []string 9144 opt IteratorOptions 9145 m map[string]*stringReduceFloatPoint 9146 points []FloatPoint 9147 } 9148 9149 // newStringStreamFloatIterator returns a new instance of stringStreamFloatIterator. 9150 func newStringStreamFloatIterator(input StringIterator, createFn func() (StringPointAggregator, FloatPointEmitter), opt IteratorOptions) *stringStreamFloatIterator { 9151 return &stringStreamFloatIterator{ 9152 input: newBufStringIterator(input), 9153 create: createFn, 9154 dims: opt.GetDimensions(), 9155 opt: opt, 9156 m: make(map[string]*stringReduceFloatPoint), 9157 } 9158 } 9159 9160 // Stats returns stats from the input iterator. 9161 func (itr *stringStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() } 9162 9163 // Close closes the iterator and all child iterators. 9164 func (itr *stringStreamFloatIterator) Close() error { return itr.input.Close() } 9165 9166 // Next returns the next value for the stream iterator. 9167 func (itr *stringStreamFloatIterator) Next() (*FloatPoint, error) { 9168 // Calculate next window if we have no more points. 9169 if len(itr.points) == 0 { 9170 var err error 9171 itr.points, err = itr.reduce() 9172 if len(itr.points) == 0 { 9173 return nil, err 9174 } 9175 } 9176 9177 // Pop next point off the stack. 9178 p := &itr.points[len(itr.points)-1] 9179 itr.points = itr.points[:len(itr.points)-1] 9180 return p, nil 9181 } 9182 9183 // reduce creates and manages aggregators for every point from the input. 9184 // After aggregating a point, it always tries to emit a value using the emitter. 9185 func (itr *stringStreamFloatIterator) reduce() ([]FloatPoint, error) { 9186 // We have already read all of the input points. 9187 if itr.m == nil { 9188 return nil, nil 9189 } 9190 9191 for { 9192 // Read next point. 9193 curr, err := itr.input.Next() 9194 if err != nil { 9195 return nil, err 9196 } else if curr == nil { 9197 // Close all of the aggregators to flush any remaining points to emit. 9198 var points []FloatPoint 9199 for _, rp := range itr.m { 9200 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 9201 if err := aggregator.Close(); err != nil { 9202 return nil, err 9203 } 9204 9205 pts := rp.Emitter.Emit() 9206 if len(pts) == 0 { 9207 continue 9208 } 9209 9210 for i := range pts { 9211 pts[i].Name = rp.Name 9212 pts[i].Tags = rp.Tags 9213 } 9214 points = append(points, pts...) 9215 } 9216 } 9217 9218 // Eliminate the aggregators and emitters. 9219 itr.m = nil 9220 return points, nil 9221 } else if curr.Nil { 9222 continue 9223 } 9224 tags := curr.Tags.Subset(itr.dims) 9225 9226 id := curr.Name 9227 if len(tags.m) > 0 { 9228 id += "\x00" + tags.ID() 9229 } 9230 9231 // Retrieve the aggregator for this name/tag combination or create one. 9232 rp := itr.m[id] 9233 if rp == nil { 9234 aggregator, emitter := itr.create() 9235 rp = &stringReduceFloatPoint{ 9236 Name: curr.Name, 9237 Tags: tags, 9238 Aggregator: aggregator, 9239 Emitter: emitter, 9240 } 9241 itr.m[id] = rp 9242 } 9243 rp.Aggregator.AggregateString(curr) 9244 9245 // Attempt to emit points from the aggregator. 9246 points := rp.Emitter.Emit() 9247 if len(points) == 0 { 9248 continue 9249 } 9250 9251 for i := range points { 9252 points[i].Name = rp.Name 9253 points[i].Tags = rp.Tags 9254 } 9255 return points, nil 9256 } 9257 } 9258 9259 // stringReduceIntegerIterator executes a reducer for every interval and buffers the result. 9260 type stringReduceIntegerIterator struct { 9261 input *bufStringIterator 9262 create func() (StringPointAggregator, IntegerPointEmitter) 9263 dims []string 9264 opt IteratorOptions 9265 points []IntegerPoint 9266 keepTags bool 9267 } 9268 9269 func newStringReduceIntegerIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, IntegerPointEmitter)) *stringReduceIntegerIterator { 9270 return &stringReduceIntegerIterator{ 9271 input: newBufStringIterator(input), 9272 create: createFn, 9273 dims: opt.GetDimensions(), 9274 opt: opt, 9275 } 9276 } 9277 9278 // Stats returns stats from the input iterator. 9279 func (itr *stringReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() } 9280 9281 // Close closes the iterator and all child iterators. 9282 func (itr *stringReduceIntegerIterator) Close() error { return itr.input.Close() } 9283 9284 // Next returns the minimum value for the next available interval. 9285 func (itr *stringReduceIntegerIterator) Next() (*IntegerPoint, error) { 9286 // Calculate next window if we have no more points. 9287 if len(itr.points) == 0 { 9288 var err error 9289 itr.points, err = itr.reduce() 9290 if len(itr.points) == 0 { 9291 return nil, err 9292 } 9293 } 9294 9295 // Pop next point off the stack. 9296 p := &itr.points[len(itr.points)-1] 9297 itr.points = itr.points[:len(itr.points)-1] 9298 return p, nil 9299 } 9300 9301 // stringReduceIntegerPoint stores the reduced data for a name/tag combination. 9302 type stringReduceIntegerPoint struct { 9303 Name string 9304 Tags Tags 9305 Aggregator StringPointAggregator 9306 Emitter IntegerPointEmitter 9307 } 9308 9309 // reduce executes fn once for every point in the next window. 9310 // The previous value for the dimension is passed to fn. 9311 func (itr *stringReduceIntegerIterator) reduce() ([]IntegerPoint, error) { 9312 // Calculate next window. 9313 var ( 9314 startTime, endTime int64 9315 window struct { 9316 name string 9317 tags string 9318 } 9319 ) 9320 for { 9321 p, err := itr.input.Next() 9322 if err != nil || p == nil { 9323 return nil, err 9324 } else if p.Nil { 9325 continue 9326 } 9327 9328 // Unread the point so it can be processed. 9329 itr.input.unread(p) 9330 startTime, endTime = itr.opt.Window(p.Time) 9331 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 9332 break 9333 } 9334 9335 // Create points by tags. 9336 m := make(map[string]*stringReduceIntegerPoint) 9337 for { 9338 // Read next point. 9339 curr, err := itr.input.NextInWindow(startTime, endTime) 9340 if err != nil { 9341 return nil, err 9342 } else if curr == nil { 9343 break 9344 } else if curr.Nil { 9345 continue 9346 } else if curr.Name != window.name { 9347 itr.input.unread(curr) 9348 break 9349 } 9350 9351 // Ensure this point is within the same final window. 9352 if curr.Name != window.name { 9353 itr.input.unread(curr) 9354 break 9355 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 9356 itr.input.unread(curr) 9357 break 9358 } 9359 9360 // Retrieve the tags on this point for this level of the query. 9361 // This may be different than the bucket dimensions. 9362 tags := curr.Tags.Subset(itr.dims) 9363 id := tags.ID() 9364 9365 // Retrieve the aggregator for this name/tag combination or create one. 9366 rp := m[id] 9367 if rp == nil { 9368 aggregator, emitter := itr.create() 9369 rp = &stringReduceIntegerPoint{ 9370 Name: curr.Name, 9371 Tags: tags, 9372 Aggregator: aggregator, 9373 Emitter: emitter, 9374 } 9375 m[id] = rp 9376 } 9377 rp.Aggregator.AggregateString(curr) 9378 } 9379 9380 keys := make([]string, 0, len(m)) 9381 for k := range m { 9382 keys = append(keys, k) 9383 } 9384 9385 // Reverse sort points by name & tag. 9386 // This ensures a consistent order of output. 9387 if len(keys) > 0 { 9388 var sorted sort.Interface = sort.StringSlice(keys) 9389 if itr.opt.Ascending { 9390 sorted = sort.Reverse(sorted) 9391 } 9392 sort.Sort(sorted) 9393 } 9394 9395 // Assume the points are already sorted until proven otherwise. 9396 sortedByTime := true 9397 // Emit the points for each name & tag combination. 9398 a := make([]IntegerPoint, 0, len(m)) 9399 for _, k := range keys { 9400 rp := m[k] 9401 points := rp.Emitter.Emit() 9402 for i := len(points) - 1; i >= 0; i-- { 9403 points[i].Name = rp.Name 9404 if !itr.keepTags { 9405 points[i].Tags = rp.Tags 9406 } 9407 // Set the points time to the interval time if the reducer didn't provide one. 9408 if points[i].Time == ZeroTime { 9409 points[i].Time = startTime 9410 } else { 9411 sortedByTime = false 9412 } 9413 a = append(a, points[i]) 9414 } 9415 } 9416 // Points may be out of order. Perform a stable sort by time if requested. 9417 if !sortedByTime && itr.opt.Ordered { 9418 var sorted sort.Interface = integerPointsByTime(a) 9419 if itr.opt.Ascending { 9420 sorted = sort.Reverse(sorted) 9421 } 9422 sort.Stable(sorted) 9423 } 9424 return a, nil 9425 } 9426 9427 // stringStreamIntegerIterator streams inputs into the iterator and emits points gradually. 9428 type stringStreamIntegerIterator struct { 9429 input *bufStringIterator 9430 create func() (StringPointAggregator, IntegerPointEmitter) 9431 dims []string 9432 opt IteratorOptions 9433 m map[string]*stringReduceIntegerPoint 9434 points []IntegerPoint 9435 } 9436 9437 // newStringStreamIntegerIterator returns a new instance of stringStreamIntegerIterator. 9438 func newStringStreamIntegerIterator(input StringIterator, createFn func() (StringPointAggregator, IntegerPointEmitter), opt IteratorOptions) *stringStreamIntegerIterator { 9439 return &stringStreamIntegerIterator{ 9440 input: newBufStringIterator(input), 9441 create: createFn, 9442 dims: opt.GetDimensions(), 9443 opt: opt, 9444 m: make(map[string]*stringReduceIntegerPoint), 9445 } 9446 } 9447 9448 // Stats returns stats from the input iterator. 9449 func (itr *stringStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() } 9450 9451 // Close closes the iterator and all child iterators. 9452 func (itr *stringStreamIntegerIterator) Close() error { return itr.input.Close() } 9453 9454 // Next returns the next value for the stream iterator. 9455 func (itr *stringStreamIntegerIterator) Next() (*IntegerPoint, error) { 9456 // Calculate next window if we have no more points. 9457 if len(itr.points) == 0 { 9458 var err error 9459 itr.points, err = itr.reduce() 9460 if len(itr.points) == 0 { 9461 return nil, err 9462 } 9463 } 9464 9465 // Pop next point off the stack. 9466 p := &itr.points[len(itr.points)-1] 9467 itr.points = itr.points[:len(itr.points)-1] 9468 return p, nil 9469 } 9470 9471 // reduce creates and manages aggregators for every point from the input. 9472 // After aggregating a point, it always tries to emit a value using the emitter. 9473 func (itr *stringStreamIntegerIterator) reduce() ([]IntegerPoint, error) { 9474 // We have already read all of the input points. 9475 if itr.m == nil { 9476 return nil, nil 9477 } 9478 9479 for { 9480 // Read next point. 9481 curr, err := itr.input.Next() 9482 if err != nil { 9483 return nil, err 9484 } else if curr == nil { 9485 // Close all of the aggregators to flush any remaining points to emit. 9486 var points []IntegerPoint 9487 for _, rp := range itr.m { 9488 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 9489 if err := aggregator.Close(); err != nil { 9490 return nil, err 9491 } 9492 9493 pts := rp.Emitter.Emit() 9494 if len(pts) == 0 { 9495 continue 9496 } 9497 9498 for i := range pts { 9499 pts[i].Name = rp.Name 9500 pts[i].Tags = rp.Tags 9501 } 9502 points = append(points, pts...) 9503 } 9504 } 9505 9506 // Eliminate the aggregators and emitters. 9507 itr.m = nil 9508 return points, nil 9509 } else if curr.Nil { 9510 continue 9511 } 9512 tags := curr.Tags.Subset(itr.dims) 9513 9514 id := curr.Name 9515 if len(tags.m) > 0 { 9516 id += "\x00" + tags.ID() 9517 } 9518 9519 // Retrieve the aggregator for this name/tag combination or create one. 9520 rp := itr.m[id] 9521 if rp == nil { 9522 aggregator, emitter := itr.create() 9523 rp = &stringReduceIntegerPoint{ 9524 Name: curr.Name, 9525 Tags: tags, 9526 Aggregator: aggregator, 9527 Emitter: emitter, 9528 } 9529 itr.m[id] = rp 9530 } 9531 rp.Aggregator.AggregateString(curr) 9532 9533 // Attempt to emit points from the aggregator. 9534 points := rp.Emitter.Emit() 9535 if len(points) == 0 { 9536 continue 9537 } 9538 9539 for i := range points { 9540 points[i].Name = rp.Name 9541 points[i].Tags = rp.Tags 9542 } 9543 return points, nil 9544 } 9545 } 9546 9547 // stringReduceUnsignedIterator executes a reducer for every interval and buffers the result. 9548 type stringReduceUnsignedIterator struct { 9549 input *bufStringIterator 9550 create func() (StringPointAggregator, UnsignedPointEmitter) 9551 dims []string 9552 opt IteratorOptions 9553 points []UnsignedPoint 9554 keepTags bool 9555 } 9556 9557 func newStringReduceUnsignedIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, UnsignedPointEmitter)) *stringReduceUnsignedIterator { 9558 return &stringReduceUnsignedIterator{ 9559 input: newBufStringIterator(input), 9560 create: createFn, 9561 dims: opt.GetDimensions(), 9562 opt: opt, 9563 } 9564 } 9565 9566 // Stats returns stats from the input iterator. 9567 func (itr *stringReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() } 9568 9569 // Close closes the iterator and all child iterators. 9570 func (itr *stringReduceUnsignedIterator) Close() error { return itr.input.Close() } 9571 9572 // Next returns the minimum value for the next available interval. 9573 func (itr *stringReduceUnsignedIterator) Next() (*UnsignedPoint, error) { 9574 // Calculate next window if we have no more points. 9575 if len(itr.points) == 0 { 9576 var err error 9577 itr.points, err = itr.reduce() 9578 if len(itr.points) == 0 { 9579 return nil, err 9580 } 9581 } 9582 9583 // Pop next point off the stack. 9584 p := &itr.points[len(itr.points)-1] 9585 itr.points = itr.points[:len(itr.points)-1] 9586 return p, nil 9587 } 9588 9589 // stringReduceUnsignedPoint stores the reduced data for a name/tag combination. 9590 type stringReduceUnsignedPoint struct { 9591 Name string 9592 Tags Tags 9593 Aggregator StringPointAggregator 9594 Emitter UnsignedPointEmitter 9595 } 9596 9597 // reduce executes fn once for every point in the next window. 9598 // The previous value for the dimension is passed to fn. 9599 func (itr *stringReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) { 9600 // Calculate next window. 9601 var ( 9602 startTime, endTime int64 9603 window struct { 9604 name string 9605 tags string 9606 } 9607 ) 9608 for { 9609 p, err := itr.input.Next() 9610 if err != nil || p == nil { 9611 return nil, err 9612 } else if p.Nil { 9613 continue 9614 } 9615 9616 // Unread the point so it can be processed. 9617 itr.input.unread(p) 9618 startTime, endTime = itr.opt.Window(p.Time) 9619 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 9620 break 9621 } 9622 9623 // Create points by tags. 9624 m := make(map[string]*stringReduceUnsignedPoint) 9625 for { 9626 // Read next point. 9627 curr, err := itr.input.NextInWindow(startTime, endTime) 9628 if err != nil { 9629 return nil, err 9630 } else if curr == nil { 9631 break 9632 } else if curr.Nil { 9633 continue 9634 } else if curr.Name != window.name { 9635 itr.input.unread(curr) 9636 break 9637 } 9638 9639 // Ensure this point is within the same final window. 9640 if curr.Name != window.name { 9641 itr.input.unread(curr) 9642 break 9643 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 9644 itr.input.unread(curr) 9645 break 9646 } 9647 9648 // Retrieve the tags on this point for this level of the query. 9649 // This may be different than the bucket dimensions. 9650 tags := curr.Tags.Subset(itr.dims) 9651 id := tags.ID() 9652 9653 // Retrieve the aggregator for this name/tag combination or create one. 9654 rp := m[id] 9655 if rp == nil { 9656 aggregator, emitter := itr.create() 9657 rp = &stringReduceUnsignedPoint{ 9658 Name: curr.Name, 9659 Tags: tags, 9660 Aggregator: aggregator, 9661 Emitter: emitter, 9662 } 9663 m[id] = rp 9664 } 9665 rp.Aggregator.AggregateString(curr) 9666 } 9667 9668 keys := make([]string, 0, len(m)) 9669 for k := range m { 9670 keys = append(keys, k) 9671 } 9672 9673 // Reverse sort points by name & tag. 9674 // This ensures a consistent order of output. 9675 if len(keys) > 0 { 9676 var sorted sort.Interface = sort.StringSlice(keys) 9677 if itr.opt.Ascending { 9678 sorted = sort.Reverse(sorted) 9679 } 9680 sort.Sort(sorted) 9681 } 9682 9683 // Assume the points are already sorted until proven otherwise. 9684 sortedByTime := true 9685 // Emit the points for each name & tag combination. 9686 a := make([]UnsignedPoint, 0, len(m)) 9687 for _, k := range keys { 9688 rp := m[k] 9689 points := rp.Emitter.Emit() 9690 for i := len(points) - 1; i >= 0; i-- { 9691 points[i].Name = rp.Name 9692 if !itr.keepTags { 9693 points[i].Tags = rp.Tags 9694 } 9695 // Set the points time to the interval time if the reducer didn't provide one. 9696 if points[i].Time == ZeroTime { 9697 points[i].Time = startTime 9698 } else { 9699 sortedByTime = false 9700 } 9701 a = append(a, points[i]) 9702 } 9703 } 9704 // Points may be out of order. Perform a stable sort by time if requested. 9705 if !sortedByTime && itr.opt.Ordered { 9706 var sorted sort.Interface = unsignedPointsByTime(a) 9707 if itr.opt.Ascending { 9708 sorted = sort.Reverse(sorted) 9709 } 9710 sort.Stable(sorted) 9711 } 9712 return a, nil 9713 } 9714 9715 // stringStreamUnsignedIterator streams inputs into the iterator and emits points gradually. 9716 type stringStreamUnsignedIterator struct { 9717 input *bufStringIterator 9718 create func() (StringPointAggregator, UnsignedPointEmitter) 9719 dims []string 9720 opt IteratorOptions 9721 m map[string]*stringReduceUnsignedPoint 9722 points []UnsignedPoint 9723 } 9724 9725 // newStringStreamUnsignedIterator returns a new instance of stringStreamUnsignedIterator. 9726 func newStringStreamUnsignedIterator(input StringIterator, createFn func() (StringPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *stringStreamUnsignedIterator { 9727 return &stringStreamUnsignedIterator{ 9728 input: newBufStringIterator(input), 9729 create: createFn, 9730 dims: opt.GetDimensions(), 9731 opt: opt, 9732 m: make(map[string]*stringReduceUnsignedPoint), 9733 } 9734 } 9735 9736 // Stats returns stats from the input iterator. 9737 func (itr *stringStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() } 9738 9739 // Close closes the iterator and all child iterators. 9740 func (itr *stringStreamUnsignedIterator) Close() error { return itr.input.Close() } 9741 9742 // Next returns the next value for the stream iterator. 9743 func (itr *stringStreamUnsignedIterator) Next() (*UnsignedPoint, error) { 9744 // Calculate next window if we have no more points. 9745 if len(itr.points) == 0 { 9746 var err error 9747 itr.points, err = itr.reduce() 9748 if len(itr.points) == 0 { 9749 return nil, err 9750 } 9751 } 9752 9753 // Pop next point off the stack. 9754 p := &itr.points[len(itr.points)-1] 9755 itr.points = itr.points[:len(itr.points)-1] 9756 return p, nil 9757 } 9758 9759 // reduce creates and manages aggregators for every point from the input. 9760 // After aggregating a point, it always tries to emit a value using the emitter. 9761 func (itr *stringStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) { 9762 // We have already read all of the input points. 9763 if itr.m == nil { 9764 return nil, nil 9765 } 9766 9767 for { 9768 // Read next point. 9769 curr, err := itr.input.Next() 9770 if err != nil { 9771 return nil, err 9772 } else if curr == nil { 9773 // Close all of the aggregators to flush any remaining points to emit. 9774 var points []UnsignedPoint 9775 for _, rp := range itr.m { 9776 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 9777 if err := aggregator.Close(); err != nil { 9778 return nil, err 9779 } 9780 9781 pts := rp.Emitter.Emit() 9782 if len(pts) == 0 { 9783 continue 9784 } 9785 9786 for i := range pts { 9787 pts[i].Name = rp.Name 9788 pts[i].Tags = rp.Tags 9789 } 9790 points = append(points, pts...) 9791 } 9792 } 9793 9794 // Eliminate the aggregators and emitters. 9795 itr.m = nil 9796 return points, nil 9797 } else if curr.Nil { 9798 continue 9799 } 9800 tags := curr.Tags.Subset(itr.dims) 9801 9802 id := curr.Name 9803 if len(tags.m) > 0 { 9804 id += "\x00" + tags.ID() 9805 } 9806 9807 // Retrieve the aggregator for this name/tag combination or create one. 9808 rp := itr.m[id] 9809 if rp == nil { 9810 aggregator, emitter := itr.create() 9811 rp = &stringReduceUnsignedPoint{ 9812 Name: curr.Name, 9813 Tags: tags, 9814 Aggregator: aggregator, 9815 Emitter: emitter, 9816 } 9817 itr.m[id] = rp 9818 } 9819 rp.Aggregator.AggregateString(curr) 9820 9821 // Attempt to emit points from the aggregator. 9822 points := rp.Emitter.Emit() 9823 if len(points) == 0 { 9824 continue 9825 } 9826 9827 for i := range points { 9828 points[i].Name = rp.Name 9829 points[i].Tags = rp.Tags 9830 } 9831 return points, nil 9832 } 9833 } 9834 9835 // stringReduceStringIterator executes a reducer for every interval and buffers the result. 9836 type stringReduceStringIterator struct { 9837 input *bufStringIterator 9838 create func() (StringPointAggregator, StringPointEmitter) 9839 dims []string 9840 opt IteratorOptions 9841 points []StringPoint 9842 keepTags bool 9843 } 9844 9845 func newStringReduceStringIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, StringPointEmitter)) *stringReduceStringIterator { 9846 return &stringReduceStringIterator{ 9847 input: newBufStringIterator(input), 9848 create: createFn, 9849 dims: opt.GetDimensions(), 9850 opt: opt, 9851 } 9852 } 9853 9854 // Stats returns stats from the input iterator. 9855 func (itr *stringReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() } 9856 9857 // Close closes the iterator and all child iterators. 9858 func (itr *stringReduceStringIterator) Close() error { return itr.input.Close() } 9859 9860 // Next returns the minimum value for the next available interval. 9861 func (itr *stringReduceStringIterator) Next() (*StringPoint, error) { 9862 // Calculate next window if we have no more points. 9863 if len(itr.points) == 0 { 9864 var err error 9865 itr.points, err = itr.reduce() 9866 if len(itr.points) == 0 { 9867 return nil, err 9868 } 9869 } 9870 9871 // Pop next point off the stack. 9872 p := &itr.points[len(itr.points)-1] 9873 itr.points = itr.points[:len(itr.points)-1] 9874 return p, nil 9875 } 9876 9877 // stringReduceStringPoint stores the reduced data for a name/tag combination. 9878 type stringReduceStringPoint struct { 9879 Name string 9880 Tags Tags 9881 Aggregator StringPointAggregator 9882 Emitter StringPointEmitter 9883 } 9884 9885 // reduce executes fn once for every point in the next window. 9886 // The previous value for the dimension is passed to fn. 9887 func (itr *stringReduceStringIterator) reduce() ([]StringPoint, error) { 9888 // Calculate next window. 9889 var ( 9890 startTime, endTime int64 9891 window struct { 9892 name string 9893 tags string 9894 } 9895 ) 9896 for { 9897 p, err := itr.input.Next() 9898 if err != nil || p == nil { 9899 return nil, err 9900 } else if p.Nil { 9901 continue 9902 } 9903 9904 // Unread the point so it can be processed. 9905 itr.input.unread(p) 9906 startTime, endTime = itr.opt.Window(p.Time) 9907 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 9908 break 9909 } 9910 9911 // Create points by tags. 9912 m := make(map[string]*stringReduceStringPoint) 9913 for { 9914 // Read next point. 9915 curr, err := itr.input.NextInWindow(startTime, endTime) 9916 if err != nil { 9917 return nil, err 9918 } else if curr == nil { 9919 break 9920 } else if curr.Nil { 9921 continue 9922 } else if curr.Name != window.name { 9923 itr.input.unread(curr) 9924 break 9925 } 9926 9927 // Ensure this point is within the same final window. 9928 if curr.Name != window.name { 9929 itr.input.unread(curr) 9930 break 9931 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 9932 itr.input.unread(curr) 9933 break 9934 } 9935 9936 // Retrieve the tags on this point for this level of the query. 9937 // This may be different than the bucket dimensions. 9938 tags := curr.Tags.Subset(itr.dims) 9939 id := tags.ID() 9940 9941 // Retrieve the aggregator for this name/tag combination or create one. 9942 rp := m[id] 9943 if rp == nil { 9944 aggregator, emitter := itr.create() 9945 rp = &stringReduceStringPoint{ 9946 Name: curr.Name, 9947 Tags: tags, 9948 Aggregator: aggregator, 9949 Emitter: emitter, 9950 } 9951 m[id] = rp 9952 } 9953 rp.Aggregator.AggregateString(curr) 9954 } 9955 9956 keys := make([]string, 0, len(m)) 9957 for k := range m { 9958 keys = append(keys, k) 9959 } 9960 9961 // Reverse sort points by name & tag. 9962 // This ensures a consistent order of output. 9963 if len(keys) > 0 { 9964 var sorted sort.Interface = sort.StringSlice(keys) 9965 if itr.opt.Ascending { 9966 sorted = sort.Reverse(sorted) 9967 } 9968 sort.Sort(sorted) 9969 } 9970 9971 // Assume the points are already sorted until proven otherwise. 9972 sortedByTime := true 9973 // Emit the points for each name & tag combination. 9974 a := make([]StringPoint, 0, len(m)) 9975 for _, k := range keys { 9976 rp := m[k] 9977 points := rp.Emitter.Emit() 9978 for i := len(points) - 1; i >= 0; i-- { 9979 points[i].Name = rp.Name 9980 if !itr.keepTags { 9981 points[i].Tags = rp.Tags 9982 } 9983 // Set the points time to the interval time if the reducer didn't provide one. 9984 if points[i].Time == ZeroTime { 9985 points[i].Time = startTime 9986 } else { 9987 sortedByTime = false 9988 } 9989 a = append(a, points[i]) 9990 } 9991 } 9992 // Points may be out of order. Perform a stable sort by time if requested. 9993 if !sortedByTime && itr.opt.Ordered { 9994 var sorted sort.Interface = stringPointsByTime(a) 9995 if itr.opt.Ascending { 9996 sorted = sort.Reverse(sorted) 9997 } 9998 sort.Stable(sorted) 9999 } 10000 return a, nil 10001 } 10002 10003 // stringStreamStringIterator streams inputs into the iterator and emits points gradually. 10004 type stringStreamStringIterator struct { 10005 input *bufStringIterator 10006 create func() (StringPointAggregator, StringPointEmitter) 10007 dims []string 10008 opt IteratorOptions 10009 m map[string]*stringReduceStringPoint 10010 points []StringPoint 10011 } 10012 10013 // newStringStreamStringIterator returns a new instance of stringStreamStringIterator. 10014 func newStringStreamStringIterator(input StringIterator, createFn func() (StringPointAggregator, StringPointEmitter), opt IteratorOptions) *stringStreamStringIterator { 10015 return &stringStreamStringIterator{ 10016 input: newBufStringIterator(input), 10017 create: createFn, 10018 dims: opt.GetDimensions(), 10019 opt: opt, 10020 m: make(map[string]*stringReduceStringPoint), 10021 } 10022 } 10023 10024 // Stats returns stats from the input iterator. 10025 func (itr *stringStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() } 10026 10027 // Close closes the iterator and all child iterators. 10028 func (itr *stringStreamStringIterator) Close() error { return itr.input.Close() } 10029 10030 // Next returns the next value for the stream iterator. 10031 func (itr *stringStreamStringIterator) Next() (*StringPoint, error) { 10032 // Calculate next window if we have no more points. 10033 if len(itr.points) == 0 { 10034 var err error 10035 itr.points, err = itr.reduce() 10036 if len(itr.points) == 0 { 10037 return nil, err 10038 } 10039 } 10040 10041 // Pop next point off the stack. 10042 p := &itr.points[len(itr.points)-1] 10043 itr.points = itr.points[:len(itr.points)-1] 10044 return p, nil 10045 } 10046 10047 // reduce creates and manages aggregators for every point from the input. 10048 // After aggregating a point, it always tries to emit a value using the emitter. 10049 func (itr *stringStreamStringIterator) reduce() ([]StringPoint, error) { 10050 // We have already read all of the input points. 10051 if itr.m == nil { 10052 return nil, nil 10053 } 10054 10055 for { 10056 // Read next point. 10057 curr, err := itr.input.Next() 10058 if err != nil { 10059 return nil, err 10060 } else if curr == nil { 10061 // Close all of the aggregators to flush any remaining points to emit. 10062 var points []StringPoint 10063 for _, rp := range itr.m { 10064 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 10065 if err := aggregator.Close(); err != nil { 10066 return nil, err 10067 } 10068 10069 pts := rp.Emitter.Emit() 10070 if len(pts) == 0 { 10071 continue 10072 } 10073 10074 for i := range pts { 10075 pts[i].Name = rp.Name 10076 pts[i].Tags = rp.Tags 10077 } 10078 points = append(points, pts...) 10079 } 10080 } 10081 10082 // Eliminate the aggregators and emitters. 10083 itr.m = nil 10084 return points, nil 10085 } else if curr.Nil { 10086 continue 10087 } 10088 tags := curr.Tags.Subset(itr.dims) 10089 10090 id := curr.Name 10091 if len(tags.m) > 0 { 10092 id += "\x00" + tags.ID() 10093 } 10094 10095 // Retrieve the aggregator for this name/tag combination or create one. 10096 rp := itr.m[id] 10097 if rp == nil { 10098 aggregator, emitter := itr.create() 10099 rp = &stringReduceStringPoint{ 10100 Name: curr.Name, 10101 Tags: tags, 10102 Aggregator: aggregator, 10103 Emitter: emitter, 10104 } 10105 itr.m[id] = rp 10106 } 10107 rp.Aggregator.AggregateString(curr) 10108 10109 // Attempt to emit points from the aggregator. 10110 points := rp.Emitter.Emit() 10111 if len(points) == 0 { 10112 continue 10113 } 10114 10115 for i := range points { 10116 points[i].Name = rp.Name 10117 points[i].Tags = rp.Tags 10118 } 10119 return points, nil 10120 } 10121 } 10122 10123 // stringReduceBooleanIterator executes a reducer for every interval and buffers the result. 10124 type stringReduceBooleanIterator struct { 10125 input *bufStringIterator 10126 create func() (StringPointAggregator, BooleanPointEmitter) 10127 dims []string 10128 opt IteratorOptions 10129 points []BooleanPoint 10130 keepTags bool 10131 } 10132 10133 func newStringReduceBooleanIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, BooleanPointEmitter)) *stringReduceBooleanIterator { 10134 return &stringReduceBooleanIterator{ 10135 input: newBufStringIterator(input), 10136 create: createFn, 10137 dims: opt.GetDimensions(), 10138 opt: opt, 10139 } 10140 } 10141 10142 // Stats returns stats from the input iterator. 10143 func (itr *stringReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() } 10144 10145 // Close closes the iterator and all child iterators. 10146 func (itr *stringReduceBooleanIterator) Close() error { return itr.input.Close() } 10147 10148 // Next returns the minimum value for the next available interval. 10149 func (itr *stringReduceBooleanIterator) Next() (*BooleanPoint, error) { 10150 // Calculate next window if we have no more points. 10151 if len(itr.points) == 0 { 10152 var err error 10153 itr.points, err = itr.reduce() 10154 if len(itr.points) == 0 { 10155 return nil, err 10156 } 10157 } 10158 10159 // Pop next point off the stack. 10160 p := &itr.points[len(itr.points)-1] 10161 itr.points = itr.points[:len(itr.points)-1] 10162 return p, nil 10163 } 10164 10165 // stringReduceBooleanPoint stores the reduced data for a name/tag combination. 10166 type stringReduceBooleanPoint struct { 10167 Name string 10168 Tags Tags 10169 Aggregator StringPointAggregator 10170 Emitter BooleanPointEmitter 10171 } 10172 10173 // reduce executes fn once for every point in the next window. 10174 // The previous value for the dimension is passed to fn. 10175 func (itr *stringReduceBooleanIterator) reduce() ([]BooleanPoint, error) { 10176 // Calculate next window. 10177 var ( 10178 startTime, endTime int64 10179 window struct { 10180 name string 10181 tags string 10182 } 10183 ) 10184 for { 10185 p, err := itr.input.Next() 10186 if err != nil || p == nil { 10187 return nil, err 10188 } else if p.Nil { 10189 continue 10190 } 10191 10192 // Unread the point so it can be processed. 10193 itr.input.unread(p) 10194 startTime, endTime = itr.opt.Window(p.Time) 10195 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 10196 break 10197 } 10198 10199 // Create points by tags. 10200 m := make(map[string]*stringReduceBooleanPoint) 10201 for { 10202 // Read next point. 10203 curr, err := itr.input.NextInWindow(startTime, endTime) 10204 if err != nil { 10205 return nil, err 10206 } else if curr == nil { 10207 break 10208 } else if curr.Nil { 10209 continue 10210 } else if curr.Name != window.name { 10211 itr.input.unread(curr) 10212 break 10213 } 10214 10215 // Ensure this point is within the same final window. 10216 if curr.Name != window.name { 10217 itr.input.unread(curr) 10218 break 10219 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 10220 itr.input.unread(curr) 10221 break 10222 } 10223 10224 // Retrieve the tags on this point for this level of the query. 10225 // This may be different than the bucket dimensions. 10226 tags := curr.Tags.Subset(itr.dims) 10227 id := tags.ID() 10228 10229 // Retrieve the aggregator for this name/tag combination or create one. 10230 rp := m[id] 10231 if rp == nil { 10232 aggregator, emitter := itr.create() 10233 rp = &stringReduceBooleanPoint{ 10234 Name: curr.Name, 10235 Tags: tags, 10236 Aggregator: aggregator, 10237 Emitter: emitter, 10238 } 10239 m[id] = rp 10240 } 10241 rp.Aggregator.AggregateString(curr) 10242 } 10243 10244 keys := make([]string, 0, len(m)) 10245 for k := range m { 10246 keys = append(keys, k) 10247 } 10248 10249 // Reverse sort points by name & tag. 10250 // This ensures a consistent order of output. 10251 if len(keys) > 0 { 10252 var sorted sort.Interface = sort.StringSlice(keys) 10253 if itr.opt.Ascending { 10254 sorted = sort.Reverse(sorted) 10255 } 10256 sort.Sort(sorted) 10257 } 10258 10259 // Assume the points are already sorted until proven otherwise. 10260 sortedByTime := true 10261 // Emit the points for each name & tag combination. 10262 a := make([]BooleanPoint, 0, len(m)) 10263 for _, k := range keys { 10264 rp := m[k] 10265 points := rp.Emitter.Emit() 10266 for i := len(points) - 1; i >= 0; i-- { 10267 points[i].Name = rp.Name 10268 if !itr.keepTags { 10269 points[i].Tags = rp.Tags 10270 } 10271 // Set the points time to the interval time if the reducer didn't provide one. 10272 if points[i].Time == ZeroTime { 10273 points[i].Time = startTime 10274 } else { 10275 sortedByTime = false 10276 } 10277 a = append(a, points[i]) 10278 } 10279 } 10280 // Points may be out of order. Perform a stable sort by time if requested. 10281 if !sortedByTime && itr.opt.Ordered { 10282 var sorted sort.Interface = booleanPointsByTime(a) 10283 if itr.opt.Ascending { 10284 sorted = sort.Reverse(sorted) 10285 } 10286 sort.Stable(sorted) 10287 } 10288 return a, nil 10289 } 10290 10291 // stringStreamBooleanIterator streams inputs into the iterator and emits points gradually. 10292 type stringStreamBooleanIterator struct { 10293 input *bufStringIterator 10294 create func() (StringPointAggregator, BooleanPointEmitter) 10295 dims []string 10296 opt IteratorOptions 10297 m map[string]*stringReduceBooleanPoint 10298 points []BooleanPoint 10299 } 10300 10301 // newStringStreamBooleanIterator returns a new instance of stringStreamBooleanIterator. 10302 func newStringStreamBooleanIterator(input StringIterator, createFn func() (StringPointAggregator, BooleanPointEmitter), opt IteratorOptions) *stringStreamBooleanIterator { 10303 return &stringStreamBooleanIterator{ 10304 input: newBufStringIterator(input), 10305 create: createFn, 10306 dims: opt.GetDimensions(), 10307 opt: opt, 10308 m: make(map[string]*stringReduceBooleanPoint), 10309 } 10310 } 10311 10312 // Stats returns stats from the input iterator. 10313 func (itr *stringStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() } 10314 10315 // Close closes the iterator and all child iterators. 10316 func (itr *stringStreamBooleanIterator) Close() error { return itr.input.Close() } 10317 10318 // Next returns the next value for the stream iterator. 10319 func (itr *stringStreamBooleanIterator) Next() (*BooleanPoint, error) { 10320 // Calculate next window if we have no more points. 10321 if len(itr.points) == 0 { 10322 var err error 10323 itr.points, err = itr.reduce() 10324 if len(itr.points) == 0 { 10325 return nil, err 10326 } 10327 } 10328 10329 // Pop next point off the stack. 10330 p := &itr.points[len(itr.points)-1] 10331 itr.points = itr.points[:len(itr.points)-1] 10332 return p, nil 10333 } 10334 10335 // reduce creates and manages aggregators for every point from the input. 10336 // After aggregating a point, it always tries to emit a value using the emitter. 10337 func (itr *stringStreamBooleanIterator) reduce() ([]BooleanPoint, error) { 10338 // We have already read all of the input points. 10339 if itr.m == nil { 10340 return nil, nil 10341 } 10342 10343 for { 10344 // Read next point. 10345 curr, err := itr.input.Next() 10346 if err != nil { 10347 return nil, err 10348 } else if curr == nil { 10349 // Close all of the aggregators to flush any remaining points to emit. 10350 var points []BooleanPoint 10351 for _, rp := range itr.m { 10352 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 10353 if err := aggregator.Close(); err != nil { 10354 return nil, err 10355 } 10356 10357 pts := rp.Emitter.Emit() 10358 if len(pts) == 0 { 10359 continue 10360 } 10361 10362 for i := range pts { 10363 pts[i].Name = rp.Name 10364 pts[i].Tags = rp.Tags 10365 } 10366 points = append(points, pts...) 10367 } 10368 } 10369 10370 // Eliminate the aggregators and emitters. 10371 itr.m = nil 10372 return points, nil 10373 } else if curr.Nil { 10374 continue 10375 } 10376 tags := curr.Tags.Subset(itr.dims) 10377 10378 id := curr.Name 10379 if len(tags.m) > 0 { 10380 id += "\x00" + tags.ID() 10381 } 10382 10383 // Retrieve the aggregator for this name/tag combination or create one. 10384 rp := itr.m[id] 10385 if rp == nil { 10386 aggregator, emitter := itr.create() 10387 rp = &stringReduceBooleanPoint{ 10388 Name: curr.Name, 10389 Tags: tags, 10390 Aggregator: aggregator, 10391 Emitter: emitter, 10392 } 10393 itr.m[id] = rp 10394 } 10395 rp.Aggregator.AggregateString(curr) 10396 10397 // Attempt to emit points from the aggregator. 10398 points := rp.Emitter.Emit() 10399 if len(points) == 0 { 10400 continue 10401 } 10402 10403 for i := range points { 10404 points[i].Name = rp.Name 10405 points[i].Tags = rp.Tags 10406 } 10407 return points, nil 10408 } 10409 } 10410 10411 // stringDedupeIterator only outputs unique points. 10412 // This differs from the DistinctIterator in that it compares all aux fields too. 10413 // This iterator is relatively inefficient and should only be used on small 10414 // datasets such as meta query results. 10415 type stringDedupeIterator struct { 10416 input StringIterator 10417 m map[string]struct{} // lookup of points already sent 10418 } 10419 10420 type stringIteratorMapper struct { 10421 cur Cursor 10422 row Row 10423 driver IteratorMap // which iterator to use for the primary value, can be nil 10424 fields []IteratorMap // which iterator to use for an aux field 10425 point StringPoint 10426 } 10427 10428 func newStringIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *stringIteratorMapper { 10429 return &stringIteratorMapper{ 10430 cur: cur, 10431 driver: driver, 10432 fields: fields, 10433 point: StringPoint{ 10434 Aux: make([]interface{}, len(fields)), 10435 }, 10436 } 10437 } 10438 10439 func (itr *stringIteratorMapper) Next() (*StringPoint, error) { 10440 if !itr.cur.Scan(&itr.row) { 10441 if err := itr.cur.Err(); err != nil { 10442 return nil, err 10443 } 10444 return nil, nil 10445 } 10446 10447 itr.point.Time = itr.row.Time 10448 itr.point.Name = itr.row.Series.Name 10449 itr.point.Tags = itr.row.Series.Tags 10450 10451 if itr.driver != nil { 10452 if v := itr.driver.Value(&itr.row); v != nil { 10453 if v, ok := castToString(v); ok { 10454 itr.point.Value = v 10455 itr.point.Nil = false 10456 } else { 10457 itr.point.Value = "" 10458 itr.point.Nil = true 10459 } 10460 } else { 10461 itr.point.Value = "" 10462 itr.point.Nil = true 10463 } 10464 } 10465 for i, f := range itr.fields { 10466 itr.point.Aux[i] = f.Value(&itr.row) 10467 } 10468 return &itr.point, nil 10469 } 10470 10471 func (itr *stringIteratorMapper) Stats() IteratorStats { 10472 return itr.cur.Stats() 10473 } 10474 10475 func (itr *stringIteratorMapper) Close() error { 10476 return itr.cur.Close() 10477 } 10478 10479 type stringFilterIterator struct { 10480 input StringIterator 10481 cond influxql.Expr 10482 opt IteratorOptions 10483 m map[string]interface{} 10484 } 10485 10486 func newStringFilterIterator(input StringIterator, cond influxql.Expr, opt IteratorOptions) StringIterator { 10487 // Strip out time conditions from the WHERE clause. 10488 // TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct. 10489 n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node { 10490 switch n := n.(type) { 10491 case *influxql.BinaryExpr: 10492 if n.LHS.String() == "time" { 10493 return &influxql.BooleanLiteral{Val: true} 10494 } 10495 } 10496 return n 10497 }) 10498 10499 cond, _ = n.(influxql.Expr) 10500 if cond == nil { 10501 return input 10502 } else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val { 10503 return input 10504 } 10505 10506 return &stringFilterIterator{ 10507 input: input, 10508 cond: cond, 10509 opt: opt, 10510 m: make(map[string]interface{}), 10511 } 10512 } 10513 10514 func (itr *stringFilterIterator) Stats() IteratorStats { return itr.input.Stats() } 10515 func (itr *stringFilterIterator) Close() error { return itr.input.Close() } 10516 10517 func (itr *stringFilterIterator) Next() (*StringPoint, error) { 10518 for { 10519 p, err := itr.input.Next() 10520 if err != nil || p == nil { 10521 return nil, err 10522 } 10523 10524 for i, ref := range itr.opt.Aux { 10525 itr.m[ref.Val] = p.Aux[i] 10526 } 10527 for k, v := range p.Tags.KeyValues() { 10528 itr.m[k] = v 10529 } 10530 10531 if !influxql.EvalBool(itr.cond, itr.m) { 10532 continue 10533 } 10534 return p, nil 10535 } 10536 } 10537 10538 type stringTagSubsetIterator struct { 10539 input StringIterator 10540 point StringPoint 10541 lastTags Tags 10542 dimensions []string 10543 } 10544 10545 func newStringTagSubsetIterator(input StringIterator, opt IteratorOptions) *stringTagSubsetIterator { 10546 return &stringTagSubsetIterator{ 10547 input: input, 10548 dimensions: opt.GetDimensions(), 10549 } 10550 } 10551 10552 func (itr *stringTagSubsetIterator) Next() (*StringPoint, error) { 10553 p, err := itr.input.Next() 10554 if err != nil { 10555 return nil, err 10556 } else if p == nil { 10557 return nil, nil 10558 } 10559 10560 itr.point.Name = p.Name 10561 if !p.Tags.Equal(itr.lastTags) { 10562 itr.point.Tags = p.Tags.Subset(itr.dimensions) 10563 itr.lastTags = p.Tags 10564 } 10565 itr.point.Time = p.Time 10566 itr.point.Value = p.Value 10567 itr.point.Aux = p.Aux 10568 itr.point.Aggregated = p.Aggregated 10569 itr.point.Nil = p.Nil 10570 return &itr.point, nil 10571 } 10572 10573 func (itr *stringTagSubsetIterator) Stats() IteratorStats { 10574 return itr.input.Stats() 10575 } 10576 10577 func (itr *stringTagSubsetIterator) Close() error { 10578 return itr.input.Close() 10579 } 10580 10581 // newStringDedupeIterator returns a new instance of stringDedupeIterator. 10582 func newStringDedupeIterator(input StringIterator) *stringDedupeIterator { 10583 return &stringDedupeIterator{ 10584 input: input, 10585 m: make(map[string]struct{}), 10586 } 10587 } 10588 10589 // Stats returns stats from the input iterator. 10590 func (itr *stringDedupeIterator) Stats() IteratorStats { return itr.input.Stats() } 10591 10592 // Close closes the iterator and all child iterators. 10593 func (itr *stringDedupeIterator) Close() error { return itr.input.Close() } 10594 10595 // Next returns the next unique point from the input iterator. 10596 func (itr *stringDedupeIterator) Next() (*StringPoint, error) { 10597 for { 10598 // Read next point. 10599 p, err := itr.input.Next() 10600 if p == nil || err != nil { 10601 return nil, err 10602 } 10603 10604 // Serialize to bytes to store in lookup. 10605 buf, err := proto.Marshal(encodeStringPoint(p)) 10606 if err != nil { 10607 return nil, err 10608 } 10609 10610 // If the point has already been output then move to the next point. 10611 if _, ok := itr.m[string(buf)]; ok { 10612 continue 10613 } 10614 10615 // Otherwise mark it as emitted and return point. 10616 itr.m[string(buf)] = struct{}{} 10617 return p, nil 10618 } 10619 } 10620 10621 // stringReaderIterator represents an iterator that streams from a reader. 10622 type stringReaderIterator struct { 10623 r io.Reader 10624 dec *StringPointDecoder 10625 } 10626 10627 // newStringReaderIterator returns a new instance of stringReaderIterator. 10628 func newStringReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *stringReaderIterator { 10629 dec := NewStringPointDecoder(ctx, r) 10630 dec.stats = stats 10631 10632 return &stringReaderIterator{ 10633 r: r, 10634 dec: dec, 10635 } 10636 } 10637 10638 // Stats returns stats about points processed. 10639 func (itr *stringReaderIterator) Stats() IteratorStats { return itr.dec.stats } 10640 10641 // Close closes the underlying reader, if applicable. 10642 func (itr *stringReaderIterator) Close() error { 10643 if r, ok := itr.r.(io.ReadCloser); ok { 10644 return r.Close() 10645 } 10646 return nil 10647 } 10648 10649 // Next returns the next point from the iterator. 10650 func (itr *stringReaderIterator) Next() (*StringPoint, error) { 10651 // OPTIMIZE(benbjohnson): Reuse point on iterator. 10652 10653 // Unmarshal next point. 10654 p := &StringPoint{} 10655 if err := itr.dec.DecodeStringPoint(p); err == io.EOF { 10656 return nil, nil 10657 } else if err != nil { 10658 return nil, err 10659 } 10660 return p, nil 10661 } 10662 10663 // BooleanIterator represents a stream of boolean points. 10664 type BooleanIterator interface { 10665 Iterator 10666 Next() (*BooleanPoint, error) 10667 } 10668 10669 // newBooleanIterators converts a slice of Iterator to a slice of BooleanIterator. 10670 // Drop and closes any iterator in itrs that is not a BooleanIterator and cannot 10671 // be cast to a BooleanIterator. 10672 func newBooleanIterators(itrs []Iterator) []BooleanIterator { 10673 a := make([]BooleanIterator, 0, len(itrs)) 10674 for _, itr := range itrs { 10675 switch itr := itr.(type) { 10676 case BooleanIterator: 10677 a = append(a, itr) 10678 default: 10679 itr.Close() 10680 } 10681 } 10682 return a 10683 } 10684 10685 // bufBooleanIterator represents a buffered BooleanIterator. 10686 type bufBooleanIterator struct { 10687 itr BooleanIterator 10688 buf *BooleanPoint 10689 } 10690 10691 // newBufBooleanIterator returns a buffered BooleanIterator. 10692 func newBufBooleanIterator(itr BooleanIterator) *bufBooleanIterator { 10693 return &bufBooleanIterator{itr: itr} 10694 } 10695 10696 // Stats returns statistics from the input iterator. 10697 func (itr *bufBooleanIterator) Stats() IteratorStats { return itr.itr.Stats() } 10698 10699 // Close closes the underlying iterator. 10700 func (itr *bufBooleanIterator) Close() error { return itr.itr.Close() } 10701 10702 // peek returns the next point without removing it from the iterator. 10703 func (itr *bufBooleanIterator) peek() (*BooleanPoint, error) { 10704 p, err := itr.Next() 10705 if err != nil { 10706 return nil, err 10707 } 10708 itr.unread(p) 10709 return p, nil 10710 } 10711 10712 // peekTime returns the time of the next point. 10713 // Returns zero time if no more points available. 10714 func (itr *bufBooleanIterator) peekTime() (int64, error) { 10715 p, err := itr.peek() 10716 if p == nil || err != nil { 10717 return ZeroTime, err 10718 } 10719 return p.Time, nil 10720 } 10721 10722 // Next returns the current buffer, if exists, or calls the underlying iterator. 10723 func (itr *bufBooleanIterator) Next() (*BooleanPoint, error) { 10724 buf := itr.buf 10725 if buf != nil { 10726 itr.buf = nil 10727 return buf, nil 10728 } 10729 return itr.itr.Next() 10730 } 10731 10732 // NextInWindow returns the next value if it is between [startTime, endTime). 10733 // If the next value is outside the range then it is moved to the buffer. 10734 func (itr *bufBooleanIterator) NextInWindow(startTime, endTime int64) (*BooleanPoint, error) { 10735 v, err := itr.Next() 10736 if v == nil || err != nil { 10737 return nil, err 10738 } else if t := v.Time; t >= endTime || t < startTime { 10739 itr.unread(v) 10740 return nil, nil 10741 } 10742 return v, nil 10743 } 10744 10745 // unread sets v to the buffer. It is read on the next call to Next(). 10746 func (itr *bufBooleanIterator) unread(v *BooleanPoint) { itr.buf = v } 10747 10748 // booleanMergeIterator represents an iterator that combines multiple boolean iterators. 10749 type booleanMergeIterator struct { 10750 inputs []BooleanIterator 10751 heap *booleanMergeHeap 10752 init bool 10753 10754 closed bool 10755 mu sync.RWMutex 10756 10757 // Current iterator and window. 10758 curr *booleanMergeHeapItem 10759 window struct { 10760 name string 10761 tags string 10762 startTime int64 10763 endTime int64 10764 } 10765 } 10766 10767 // newBooleanMergeIterator returns a new instance of booleanMergeIterator. 10768 func newBooleanMergeIterator(inputs []BooleanIterator, opt IteratorOptions) *booleanMergeIterator { 10769 itr := &booleanMergeIterator{ 10770 inputs: inputs, 10771 heap: &booleanMergeHeap{ 10772 items: make([]*booleanMergeHeapItem, 0, len(inputs)), 10773 opt: opt, 10774 }, 10775 } 10776 10777 // Initialize heap items. 10778 for _, input := range inputs { 10779 // Wrap in buffer, ignore any inputs without anymore points. 10780 bufInput := newBufBooleanIterator(input) 10781 10782 // Append to the heap. 10783 itr.heap.items = append(itr.heap.items, &booleanMergeHeapItem{itr: bufInput}) 10784 } 10785 10786 return itr 10787 } 10788 10789 // Stats returns an aggregation of stats from the underlying iterators. 10790 func (itr *booleanMergeIterator) Stats() IteratorStats { 10791 var stats IteratorStats 10792 for _, input := range itr.inputs { 10793 stats.Add(input.Stats()) 10794 } 10795 return stats 10796 } 10797 10798 // Close closes the underlying iterators. 10799 func (itr *booleanMergeIterator) Close() error { 10800 itr.mu.Lock() 10801 defer itr.mu.Unlock() 10802 10803 for _, input := range itr.inputs { 10804 input.Close() 10805 } 10806 itr.curr = nil 10807 itr.inputs = nil 10808 itr.heap.items = nil 10809 itr.closed = true 10810 return nil 10811 } 10812 10813 // Next returns the next point from the iterator. 10814 func (itr *booleanMergeIterator) Next() (*BooleanPoint, error) { 10815 itr.mu.RLock() 10816 defer itr.mu.RUnlock() 10817 if itr.closed { 10818 return nil, nil 10819 } 10820 10821 // Initialize the heap. This needs to be done lazily on the first call to this iterator 10822 // so that iterator initialization done through the Select() call returns quickly. 10823 // Queries can only be interrupted after the Select() call completes so any operations 10824 // done during iterator creation cannot be interrupted, which is why we do it here 10825 // instead so an interrupt can happen while initializing the heap. 10826 if !itr.init { 10827 items := itr.heap.items 10828 itr.heap.items = make([]*booleanMergeHeapItem, 0, len(items)) 10829 for _, item := range items { 10830 if p, err := item.itr.peek(); err != nil { 10831 return nil, err 10832 } else if p == nil { 10833 continue 10834 } 10835 itr.heap.items = append(itr.heap.items, item) 10836 } 10837 heap.Init(itr.heap) 10838 itr.init = true 10839 } 10840 10841 for { 10842 // Retrieve the next iterator if we don't have one. 10843 if itr.curr == nil { 10844 if len(itr.heap.items) == 0 { 10845 return nil, nil 10846 } 10847 itr.curr = heap.Pop(itr.heap).(*booleanMergeHeapItem) 10848 10849 // Read point and set current window. 10850 p, err := itr.curr.itr.Next() 10851 if err != nil { 10852 return nil, err 10853 } 10854 tags := p.Tags.Subset(itr.heap.opt.Dimensions) 10855 itr.window.name, itr.window.tags = p.Name, tags.ID() 10856 itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time) 10857 return p, nil 10858 } 10859 10860 // Read the next point from the current iterator. 10861 p, err := itr.curr.itr.Next() 10862 if err != nil { 10863 return nil, err 10864 } 10865 10866 // If there are no more points then remove iterator from heap and find next. 10867 if p == nil { 10868 itr.curr = nil 10869 continue 10870 } 10871 10872 // Check if the point is inside of our current window. 10873 inWindow := true 10874 if window := itr.window; window.name != p.Name { 10875 inWindow = false 10876 } else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() { 10877 inWindow = false 10878 } else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime { 10879 inWindow = false 10880 } else if !opt.Ascending && p.Time < window.startTime { 10881 inWindow = false 10882 } 10883 10884 // If it's outside our window then push iterator back on the heap and find new iterator. 10885 if !inWindow { 10886 itr.curr.itr.unread(p) 10887 heap.Push(itr.heap, itr.curr) 10888 itr.curr = nil 10889 continue 10890 } 10891 10892 return p, nil 10893 } 10894 } 10895 10896 // booleanMergeHeap represents a heap of booleanMergeHeapItems. 10897 // Items are sorted by their next window and then by name/tags. 10898 type booleanMergeHeap struct { 10899 opt IteratorOptions 10900 items []*booleanMergeHeapItem 10901 } 10902 10903 func (h *booleanMergeHeap) Len() int { return len(h.items) } 10904 func (h *booleanMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] } 10905 func (h *booleanMergeHeap) Less(i, j int) bool { 10906 x, err := h.items[i].itr.peek() 10907 if err != nil { 10908 return true 10909 } 10910 y, err := h.items[j].itr.peek() 10911 if err != nil { 10912 return false 10913 } 10914 10915 if h.opt.Ascending { 10916 if x.Name != y.Name { 10917 return x.Name < y.Name 10918 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() { 10919 return xTags.ID() < yTags.ID() 10920 } 10921 } else { 10922 if x.Name != y.Name { 10923 return x.Name > y.Name 10924 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() { 10925 return xTags.ID() > yTags.ID() 10926 } 10927 } 10928 10929 xt, _ := h.opt.Window(x.Time) 10930 yt, _ := h.opt.Window(y.Time) 10931 10932 if h.opt.Ascending { 10933 return xt < yt 10934 } 10935 return xt > yt 10936 } 10937 10938 func (h *booleanMergeHeap) Push(x interface{}) { 10939 h.items = append(h.items, x.(*booleanMergeHeapItem)) 10940 } 10941 10942 func (h *booleanMergeHeap) Pop() interface{} { 10943 old := h.items 10944 n := len(old) 10945 item := old[n-1] 10946 h.items = old[0 : n-1] 10947 return item 10948 } 10949 10950 type booleanMergeHeapItem struct { 10951 itr *bufBooleanIterator 10952 } 10953 10954 // booleanSortedMergeIterator is an iterator that sorts and merges multiple iterators into one. 10955 type booleanSortedMergeIterator struct { 10956 inputs []BooleanIterator 10957 heap *booleanSortedMergeHeap 10958 init bool 10959 } 10960 10961 // newBooleanSortedMergeIterator returns an instance of booleanSortedMergeIterator. 10962 func newBooleanSortedMergeIterator(inputs []BooleanIterator, opt IteratorOptions) Iterator { 10963 itr := &booleanSortedMergeIterator{ 10964 inputs: inputs, 10965 heap: &booleanSortedMergeHeap{ 10966 items: make([]*booleanSortedMergeHeapItem, 0, len(inputs)), 10967 opt: opt, 10968 }, 10969 } 10970 10971 // Initialize heap items. 10972 for _, input := range inputs { 10973 // Append to the heap. 10974 itr.heap.items = append(itr.heap.items, &booleanSortedMergeHeapItem{itr: input}) 10975 } 10976 10977 return itr 10978 } 10979 10980 // Stats returns an aggregation of stats from the underlying iterators. 10981 func (itr *booleanSortedMergeIterator) Stats() IteratorStats { 10982 var stats IteratorStats 10983 for _, input := range itr.inputs { 10984 stats.Add(input.Stats()) 10985 } 10986 return stats 10987 } 10988 10989 // Close closes the underlying iterators. 10990 func (itr *booleanSortedMergeIterator) Close() error { 10991 for _, input := range itr.inputs { 10992 input.Close() 10993 } 10994 return nil 10995 } 10996 10997 // Next returns the next points from the iterator. 10998 func (itr *booleanSortedMergeIterator) Next() (*BooleanPoint, error) { return itr.pop() } 10999 11000 // pop returns the next point from the heap. 11001 // Reads the next point from item's cursor and puts it back on the heap. 11002 func (itr *booleanSortedMergeIterator) pop() (*BooleanPoint, error) { 11003 // Initialize the heap. See the MergeIterator to see why this has to be done lazily. 11004 if !itr.init { 11005 items := itr.heap.items 11006 itr.heap.items = make([]*booleanSortedMergeHeapItem, 0, len(items)) 11007 for _, item := range items { 11008 var err error 11009 if item.point, err = item.itr.Next(); err != nil { 11010 return nil, err 11011 } else if item.point == nil { 11012 continue 11013 } 11014 itr.heap.items = append(itr.heap.items, item) 11015 } 11016 heap.Init(itr.heap) 11017 itr.init = true 11018 } 11019 11020 if len(itr.heap.items) == 0 { 11021 return nil, nil 11022 } 11023 11024 // Read the next item from the heap. 11025 item := heap.Pop(itr.heap).(*booleanSortedMergeHeapItem) 11026 if item.err != nil { 11027 return nil, item.err 11028 } else if item.point == nil { 11029 return nil, nil 11030 } 11031 11032 // Copy the point for return. 11033 p := item.point.Clone() 11034 11035 // Read the next item from the cursor. Push back to heap if one exists. 11036 if item.point, item.err = item.itr.Next(); item.point != nil { 11037 heap.Push(itr.heap, item) 11038 } 11039 11040 return p, nil 11041 } 11042 11043 // booleanSortedMergeHeap represents a heap of booleanSortedMergeHeapItems. 11044 // Items are sorted with the following priority: 11045 // - By their measurement name; 11046 // - By their tag keys/values; 11047 // - By time; or 11048 // - By their Aux field values. 11049 type booleanSortedMergeHeap struct { 11050 opt IteratorOptions 11051 items []*booleanSortedMergeHeapItem 11052 } 11053 11054 func (h *booleanSortedMergeHeap) Len() int { return len(h.items) } 11055 func (h *booleanSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] } 11056 func (h *booleanSortedMergeHeap) Less(i, j int) bool { 11057 x, y := h.items[i].point, h.items[j].point 11058 11059 if h.opt.Ascending { 11060 if x.Name != y.Name { 11061 return x.Name < y.Name 11062 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) { 11063 return xTags.ID() < yTags.ID() 11064 } 11065 11066 if x.Time != y.Time { 11067 return x.Time < y.Time 11068 } 11069 11070 if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) { 11071 for i := 0; i < len(x.Aux); i++ { 11072 v1, ok1 := x.Aux[i].(string) 11073 v2, ok2 := y.Aux[i].(string) 11074 if !ok1 || !ok2 { 11075 // Unsupported types used in Aux fields. Maybe they 11076 // need to be added here? 11077 return false 11078 } else if v1 == v2 { 11079 continue 11080 } 11081 return v1 < v2 11082 } 11083 } 11084 return false // Times and/or Aux fields are equal. 11085 } 11086 11087 if x.Name != y.Name { 11088 return x.Name > y.Name 11089 } else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) { 11090 return xTags.ID() > yTags.ID() 11091 } 11092 11093 if x.Time != y.Time { 11094 return x.Time > y.Time 11095 } 11096 11097 if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) { 11098 for i := 0; i < len(x.Aux); i++ { 11099 v1, ok1 := x.Aux[i].(string) 11100 v2, ok2 := y.Aux[i].(string) 11101 if !ok1 || !ok2 { 11102 // Unsupported types used in Aux fields. Maybe they 11103 // need to be added here? 11104 return false 11105 } else if v1 == v2 { 11106 continue 11107 } 11108 return v1 > v2 11109 } 11110 } 11111 return false // Times and/or Aux fields are equal. 11112 } 11113 11114 func (h *booleanSortedMergeHeap) Push(x interface{}) { 11115 h.items = append(h.items, x.(*booleanSortedMergeHeapItem)) 11116 } 11117 11118 func (h *booleanSortedMergeHeap) Pop() interface{} { 11119 old := h.items 11120 n := len(old) 11121 item := old[n-1] 11122 h.items = old[0 : n-1] 11123 return item 11124 } 11125 11126 type booleanSortedMergeHeapItem struct { 11127 point *BooleanPoint 11128 err error 11129 itr BooleanIterator 11130 } 11131 11132 // booleanIteratorScanner scans the results of a BooleanIterator into a map. 11133 type booleanIteratorScanner struct { 11134 input *bufBooleanIterator 11135 err error 11136 keys []influxql.VarRef 11137 defaultValue interface{} 11138 } 11139 11140 // newBooleanIteratorScanner creates a new IteratorScanner. 11141 func newBooleanIteratorScanner(input BooleanIterator, keys []influxql.VarRef, defaultValue interface{}) *booleanIteratorScanner { 11142 return &booleanIteratorScanner{ 11143 input: newBufBooleanIterator(input), 11144 keys: keys, 11145 defaultValue: defaultValue, 11146 } 11147 } 11148 11149 func (s *booleanIteratorScanner) Peek() (int64, string, Tags) { 11150 if s.err != nil { 11151 return ZeroTime, "", Tags{} 11152 } 11153 11154 p, err := s.input.peek() 11155 if err != nil { 11156 s.err = err 11157 return ZeroTime, "", Tags{} 11158 } else if p == nil { 11159 return ZeroTime, "", Tags{} 11160 } 11161 return p.Time, p.Name, p.Tags 11162 } 11163 11164 func (s *booleanIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) { 11165 if s.err != nil { 11166 return 11167 } 11168 11169 p, err := s.input.Next() 11170 if err != nil { 11171 s.err = err 11172 return 11173 } else if p == nil { 11174 s.useDefaults(m) 11175 return 11176 } else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) { 11177 s.useDefaults(m) 11178 s.input.unread(p) 11179 return 11180 } 11181 11182 if k := s.keys[0]; k.Val != "" { 11183 if p.Nil { 11184 if s.defaultValue != SkipDefault { 11185 m[k.Val] = castToType(s.defaultValue, k.Type) 11186 } 11187 } else { 11188 m[k.Val] = p.Value 11189 } 11190 } 11191 for i, v := range p.Aux { 11192 k := s.keys[i+1] 11193 switch v.(type) { 11194 case float64, int64, uint64, string, bool: 11195 m[k.Val] = v 11196 default: 11197 // Insert the fill value if one was specified. 11198 if s.defaultValue != SkipDefault { 11199 m[k.Val] = castToType(s.defaultValue, k.Type) 11200 } 11201 } 11202 } 11203 } 11204 11205 func (s *booleanIteratorScanner) useDefaults(m map[string]interface{}) { 11206 if s.defaultValue == SkipDefault { 11207 return 11208 } 11209 for _, k := range s.keys { 11210 if k.Val == "" { 11211 continue 11212 } 11213 m[k.Val] = castToType(s.defaultValue, k.Type) 11214 } 11215 } 11216 11217 func (s *booleanIteratorScanner) Stats() IteratorStats { return s.input.Stats() } 11218 func (s *booleanIteratorScanner) Err() error { return s.err } 11219 func (s *booleanIteratorScanner) Close() error { return s.input.Close() } 11220 11221 // booleanParallelIterator represents an iterator that pulls data in a separate goroutine. 11222 type booleanParallelIterator struct { 11223 input BooleanIterator 11224 ch chan booleanPointError 11225 11226 once sync.Once 11227 closing chan struct{} 11228 wg sync.WaitGroup 11229 } 11230 11231 // newBooleanParallelIterator returns a new instance of booleanParallelIterator. 11232 func newBooleanParallelIterator(input BooleanIterator) *booleanParallelIterator { 11233 itr := &booleanParallelIterator{ 11234 input: input, 11235 ch: make(chan booleanPointError, 256), 11236 closing: make(chan struct{}), 11237 } 11238 itr.wg.Add(1) 11239 go itr.monitor() 11240 return itr 11241 } 11242 11243 // Stats returns stats from the underlying iterator. 11244 func (itr *booleanParallelIterator) Stats() IteratorStats { return itr.input.Stats() } 11245 11246 // Close closes the underlying iterators. 11247 func (itr *booleanParallelIterator) Close() error { 11248 itr.once.Do(func() { close(itr.closing) }) 11249 itr.wg.Wait() 11250 return itr.input.Close() 11251 } 11252 11253 // Next returns the next point from the iterator. 11254 func (itr *booleanParallelIterator) Next() (*BooleanPoint, error) { 11255 v, ok := <-itr.ch 11256 if !ok { 11257 return nil, io.EOF 11258 } 11259 return v.point, v.err 11260 } 11261 11262 // monitor runs in a separate goroutine and actively pulls the next point. 11263 func (itr *booleanParallelIterator) monitor() { 11264 defer close(itr.ch) 11265 defer itr.wg.Done() 11266 11267 for { 11268 // Read next point. 11269 p, err := itr.input.Next() 11270 if p != nil { 11271 p = p.Clone() 11272 } 11273 11274 select { 11275 case <-itr.closing: 11276 return 11277 case itr.ch <- booleanPointError{point: p, err: err}: 11278 } 11279 } 11280 } 11281 11282 type booleanPointError struct { 11283 point *BooleanPoint 11284 err error 11285 } 11286 11287 // booleanLimitIterator represents an iterator that limits points per group. 11288 type booleanLimitIterator struct { 11289 input BooleanIterator 11290 opt IteratorOptions 11291 n int 11292 11293 prev struct { 11294 name string 11295 tags Tags 11296 } 11297 } 11298 11299 // newBooleanLimitIterator returns a new instance of booleanLimitIterator. 11300 func newBooleanLimitIterator(input BooleanIterator, opt IteratorOptions) *booleanLimitIterator { 11301 return &booleanLimitIterator{ 11302 input: input, 11303 opt: opt, 11304 } 11305 } 11306 11307 // Stats returns stats from the underlying iterator. 11308 func (itr *booleanLimitIterator) Stats() IteratorStats { return itr.input.Stats() } 11309 11310 // Close closes the underlying iterators. 11311 func (itr *booleanLimitIterator) Close() error { return itr.input.Close() } 11312 11313 // Next returns the next point from the iterator. 11314 func (itr *booleanLimitIterator) Next() (*BooleanPoint, error) { 11315 for { 11316 p, err := itr.input.Next() 11317 if p == nil || err != nil { 11318 return nil, err 11319 } 11320 11321 // Reset window and counter if a new window is encountered. 11322 if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) { 11323 itr.prev.name = p.Name 11324 itr.prev.tags = p.Tags 11325 itr.n = 0 11326 } 11327 11328 // Increment counter. 11329 itr.n++ 11330 11331 // Read next point if not beyond the offset. 11332 if itr.n <= itr.opt.Offset { 11333 continue 11334 } 11335 11336 // Read next point if we're beyond the limit. 11337 if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit { 11338 continue 11339 } 11340 11341 return p, nil 11342 } 11343 } 11344 11345 type booleanFillIterator struct { 11346 input *bufBooleanIterator 11347 prev BooleanPoint 11348 startTime int64 11349 endTime int64 11350 auxFields []interface{} 11351 init bool 11352 opt IteratorOptions 11353 11354 window struct { 11355 name string 11356 tags Tags 11357 time int64 11358 offset int64 11359 } 11360 } 11361 11362 func newBooleanFillIterator(input BooleanIterator, expr influxql.Expr, opt IteratorOptions) *booleanFillIterator { 11363 if opt.Fill == influxql.NullFill { 11364 if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" { 11365 opt.Fill = influxql.NumberFill 11366 opt.FillValue = false 11367 } 11368 } 11369 11370 var startTime, endTime int64 11371 if opt.Ascending { 11372 startTime, _ = opt.Window(opt.StartTime) 11373 endTime, _ = opt.Window(opt.EndTime) 11374 } else { 11375 startTime, _ = opt.Window(opt.EndTime) 11376 endTime, _ = opt.Window(opt.StartTime) 11377 } 11378 11379 var auxFields []interface{} 11380 if len(opt.Aux) > 0 { 11381 auxFields = make([]interface{}, len(opt.Aux)) 11382 } 11383 11384 return &booleanFillIterator{ 11385 input: newBufBooleanIterator(input), 11386 prev: BooleanPoint{Nil: true}, 11387 startTime: startTime, 11388 endTime: endTime, 11389 auxFields: auxFields, 11390 opt: opt, 11391 } 11392 } 11393 11394 func (itr *booleanFillIterator) Stats() IteratorStats { return itr.input.Stats() } 11395 func (itr *booleanFillIterator) Close() error { return itr.input.Close() } 11396 11397 func (itr *booleanFillIterator) Next() (*BooleanPoint, error) { 11398 if !itr.init { 11399 p, err := itr.input.peek() 11400 if p == nil || err != nil { 11401 return nil, err 11402 } 11403 itr.window.name, itr.window.tags = p.Name, p.Tags 11404 itr.window.time = itr.startTime 11405 if itr.startTime == influxql.MinTime { 11406 itr.window.time, _ = itr.opt.Window(p.Time) 11407 } 11408 if itr.opt.Location != nil { 11409 _, itr.window.offset = itr.opt.Zone(itr.window.time) 11410 } 11411 itr.init = true 11412 } 11413 11414 p, err := itr.input.Next() 11415 if err != nil { 11416 return nil, err 11417 } 11418 11419 // Check if the next point is outside of our window or is nil. 11420 if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() { 11421 // If we are inside of an interval, unread the point and continue below to 11422 // constructing a new point. 11423 if itr.opt.Ascending && itr.window.time <= itr.endTime { 11424 itr.input.unread(p) 11425 p = nil 11426 goto CONSTRUCT 11427 } else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime { 11428 itr.input.unread(p) 11429 p = nil 11430 goto CONSTRUCT 11431 } 11432 11433 // We are *not* in a current interval. If there is no next point, 11434 // we are at the end of all intervals. 11435 if p == nil { 11436 return nil, nil 11437 } 11438 11439 // Set the new interval. 11440 itr.window.name, itr.window.tags = p.Name, p.Tags 11441 itr.window.time = itr.startTime 11442 if itr.window.time == influxql.MinTime { 11443 itr.window.time, _ = itr.opt.Window(p.Time) 11444 } 11445 if itr.opt.Location != nil { 11446 _, itr.window.offset = itr.opt.Zone(itr.window.time) 11447 } 11448 itr.prev = BooleanPoint{Nil: true} 11449 } 11450 11451 // Check if the point is our next expected point. 11452 CONSTRUCT: 11453 if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) { 11454 if p != nil { 11455 itr.input.unread(p) 11456 } 11457 11458 p = &BooleanPoint{ 11459 Name: itr.window.name, 11460 Tags: itr.window.tags, 11461 Time: itr.window.time, 11462 Aux: itr.auxFields, 11463 } 11464 11465 switch itr.opt.Fill { 11466 case influxql.LinearFill: 11467 fallthrough 11468 case influxql.NullFill: 11469 p.Nil = true 11470 case influxql.NumberFill: 11471 p.Value, _ = castToBoolean(itr.opt.FillValue) 11472 case influxql.PreviousFill: 11473 if !itr.prev.Nil { 11474 p.Value = itr.prev.Value 11475 p.Nil = itr.prev.Nil 11476 } else { 11477 p.Nil = true 11478 } 11479 } 11480 } else { 11481 itr.prev = *p 11482 } 11483 11484 // Advance the expected time. Do not advance to a new window here 11485 // as there may be lingering points with the same timestamp in the previous 11486 // window. 11487 if itr.opt.Ascending { 11488 itr.window.time += int64(itr.opt.Interval.Duration) 11489 } else { 11490 itr.window.time -= int64(itr.opt.Interval.Duration) 11491 } 11492 11493 // Check to see if we have passed over an offset change and adjust the time 11494 // to account for this new offset. 11495 if itr.opt.Location != nil { 11496 if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset { 11497 diff := itr.window.offset - offset 11498 if abs(diff) < int64(itr.opt.Interval.Duration) { 11499 itr.window.time += diff 11500 } 11501 itr.window.offset = offset 11502 } 11503 } 11504 return p, nil 11505 } 11506 11507 // booleanIntervalIterator represents a boolean implementation of IntervalIterator. 11508 type booleanIntervalIterator struct { 11509 input BooleanIterator 11510 opt IteratorOptions 11511 } 11512 11513 func newBooleanIntervalIterator(input BooleanIterator, opt IteratorOptions) *booleanIntervalIterator { 11514 return &booleanIntervalIterator{input: input, opt: opt} 11515 } 11516 11517 func (itr *booleanIntervalIterator) Stats() IteratorStats { return itr.input.Stats() } 11518 func (itr *booleanIntervalIterator) Close() error { return itr.input.Close() } 11519 11520 func (itr *booleanIntervalIterator) Next() (*BooleanPoint, error) { 11521 p, err := itr.input.Next() 11522 if p == nil || err != nil { 11523 return nil, err 11524 } 11525 p.Time, _ = itr.opt.Window(p.Time) 11526 // If we see the minimum allowable time, set the time to zero so we don't 11527 // break the default returned time for aggregate queries without times. 11528 if p.Time == influxql.MinTime { 11529 p.Time = 0 11530 } 11531 return p, nil 11532 } 11533 11534 // booleanInterruptIterator represents a boolean implementation of InterruptIterator. 11535 type booleanInterruptIterator struct { 11536 input BooleanIterator 11537 closing <-chan struct{} 11538 count int 11539 } 11540 11541 func newBooleanInterruptIterator(input BooleanIterator, closing <-chan struct{}) *booleanInterruptIterator { 11542 return &booleanInterruptIterator{input: input, closing: closing} 11543 } 11544 11545 func (itr *booleanInterruptIterator) Stats() IteratorStats { return itr.input.Stats() } 11546 func (itr *booleanInterruptIterator) Close() error { return itr.input.Close() } 11547 11548 func (itr *booleanInterruptIterator) Next() (*BooleanPoint, error) { 11549 // Only check if the channel is closed every N points. This 11550 // intentionally checks on both 0 and N so that if the iterator 11551 // has been interrupted before the first point is emitted it will 11552 // not emit any points. 11553 if itr.count&0xFF == 0xFF { 11554 select { 11555 case <-itr.closing: 11556 return nil, itr.Close() 11557 default: 11558 // Reset iterator count to zero and fall through to emit the next point. 11559 itr.count = 0 11560 } 11561 } 11562 11563 // Increment the counter for every point read. 11564 itr.count++ 11565 return itr.input.Next() 11566 } 11567 11568 // booleanCloseInterruptIterator represents a boolean implementation of CloseInterruptIterator. 11569 type booleanCloseInterruptIterator struct { 11570 input BooleanIterator 11571 closing <-chan struct{} 11572 done chan struct{} 11573 once sync.Once 11574 } 11575 11576 func newBooleanCloseInterruptIterator(input BooleanIterator, closing <-chan struct{}) *booleanCloseInterruptIterator { 11577 itr := &booleanCloseInterruptIterator{ 11578 input: input, 11579 closing: closing, 11580 done: make(chan struct{}), 11581 } 11582 go itr.monitor() 11583 return itr 11584 } 11585 11586 func (itr *booleanCloseInterruptIterator) monitor() { 11587 select { 11588 case <-itr.closing: 11589 itr.Close() 11590 case <-itr.done: 11591 } 11592 } 11593 11594 func (itr *booleanCloseInterruptIterator) Stats() IteratorStats { 11595 return itr.input.Stats() 11596 } 11597 11598 func (itr *booleanCloseInterruptIterator) Close() error { 11599 itr.once.Do(func() { 11600 close(itr.done) 11601 itr.input.Close() 11602 }) 11603 return nil 11604 } 11605 11606 func (itr *booleanCloseInterruptIterator) Next() (*BooleanPoint, error) { 11607 p, err := itr.input.Next() 11608 if err != nil { 11609 // Check if the iterator was closed. 11610 select { 11611 case <-itr.done: 11612 return nil, nil 11613 default: 11614 return nil, err 11615 } 11616 } 11617 return p, nil 11618 } 11619 11620 // booleanReduceFloatIterator executes a reducer for every interval and buffers the result. 11621 type booleanReduceFloatIterator struct { 11622 input *bufBooleanIterator 11623 create func() (BooleanPointAggregator, FloatPointEmitter) 11624 dims []string 11625 opt IteratorOptions 11626 points []FloatPoint 11627 keepTags bool 11628 } 11629 11630 func newBooleanReduceFloatIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, FloatPointEmitter)) *booleanReduceFloatIterator { 11631 return &booleanReduceFloatIterator{ 11632 input: newBufBooleanIterator(input), 11633 create: createFn, 11634 dims: opt.GetDimensions(), 11635 opt: opt, 11636 } 11637 } 11638 11639 // Stats returns stats from the input iterator. 11640 func (itr *booleanReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() } 11641 11642 // Close closes the iterator and all child iterators. 11643 func (itr *booleanReduceFloatIterator) Close() error { return itr.input.Close() } 11644 11645 // Next returns the minimum value for the next available interval. 11646 func (itr *booleanReduceFloatIterator) Next() (*FloatPoint, error) { 11647 // Calculate next window if we have no more points. 11648 if len(itr.points) == 0 { 11649 var err error 11650 itr.points, err = itr.reduce() 11651 if len(itr.points) == 0 { 11652 return nil, err 11653 } 11654 } 11655 11656 // Pop next point off the stack. 11657 p := &itr.points[len(itr.points)-1] 11658 itr.points = itr.points[:len(itr.points)-1] 11659 return p, nil 11660 } 11661 11662 // booleanReduceFloatPoint stores the reduced data for a name/tag combination. 11663 type booleanReduceFloatPoint struct { 11664 Name string 11665 Tags Tags 11666 Aggregator BooleanPointAggregator 11667 Emitter FloatPointEmitter 11668 } 11669 11670 // reduce executes fn once for every point in the next window. 11671 // The previous value for the dimension is passed to fn. 11672 func (itr *booleanReduceFloatIterator) reduce() ([]FloatPoint, error) { 11673 // Calculate next window. 11674 var ( 11675 startTime, endTime int64 11676 window struct { 11677 name string 11678 tags string 11679 } 11680 ) 11681 for { 11682 p, err := itr.input.Next() 11683 if err != nil || p == nil { 11684 return nil, err 11685 } else if p.Nil { 11686 continue 11687 } 11688 11689 // Unread the point so it can be processed. 11690 itr.input.unread(p) 11691 startTime, endTime = itr.opt.Window(p.Time) 11692 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 11693 break 11694 } 11695 11696 // Create points by tags. 11697 m := make(map[string]*booleanReduceFloatPoint) 11698 for { 11699 // Read next point. 11700 curr, err := itr.input.NextInWindow(startTime, endTime) 11701 if err != nil { 11702 return nil, err 11703 } else if curr == nil { 11704 break 11705 } else if curr.Nil { 11706 continue 11707 } else if curr.Name != window.name { 11708 itr.input.unread(curr) 11709 break 11710 } 11711 11712 // Ensure this point is within the same final window. 11713 if curr.Name != window.name { 11714 itr.input.unread(curr) 11715 break 11716 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 11717 itr.input.unread(curr) 11718 break 11719 } 11720 11721 // Retrieve the tags on this point for this level of the query. 11722 // This may be different than the bucket dimensions. 11723 tags := curr.Tags.Subset(itr.dims) 11724 id := tags.ID() 11725 11726 // Retrieve the aggregator for this name/tag combination or create one. 11727 rp := m[id] 11728 if rp == nil { 11729 aggregator, emitter := itr.create() 11730 rp = &booleanReduceFloatPoint{ 11731 Name: curr.Name, 11732 Tags: tags, 11733 Aggregator: aggregator, 11734 Emitter: emitter, 11735 } 11736 m[id] = rp 11737 } 11738 rp.Aggregator.AggregateBoolean(curr) 11739 } 11740 11741 keys := make([]string, 0, len(m)) 11742 for k := range m { 11743 keys = append(keys, k) 11744 } 11745 11746 // Reverse sort points by name & tag. 11747 // This ensures a consistent order of output. 11748 if len(keys) > 0 { 11749 var sorted sort.Interface = sort.StringSlice(keys) 11750 if itr.opt.Ascending { 11751 sorted = sort.Reverse(sorted) 11752 } 11753 sort.Sort(sorted) 11754 } 11755 11756 // Assume the points are already sorted until proven otherwise. 11757 sortedByTime := true 11758 // Emit the points for each name & tag combination. 11759 a := make([]FloatPoint, 0, len(m)) 11760 for _, k := range keys { 11761 rp := m[k] 11762 points := rp.Emitter.Emit() 11763 for i := len(points) - 1; i >= 0; i-- { 11764 points[i].Name = rp.Name 11765 if !itr.keepTags { 11766 points[i].Tags = rp.Tags 11767 } 11768 // Set the points time to the interval time if the reducer didn't provide one. 11769 if points[i].Time == ZeroTime { 11770 points[i].Time = startTime 11771 } else { 11772 sortedByTime = false 11773 } 11774 a = append(a, points[i]) 11775 } 11776 } 11777 // Points may be out of order. Perform a stable sort by time if requested. 11778 if !sortedByTime && itr.opt.Ordered { 11779 var sorted sort.Interface = floatPointsByTime(a) 11780 if itr.opt.Ascending { 11781 sorted = sort.Reverse(sorted) 11782 } 11783 sort.Stable(sorted) 11784 } 11785 return a, nil 11786 } 11787 11788 // booleanStreamFloatIterator streams inputs into the iterator and emits points gradually. 11789 type booleanStreamFloatIterator struct { 11790 input *bufBooleanIterator 11791 create func() (BooleanPointAggregator, FloatPointEmitter) 11792 dims []string 11793 opt IteratorOptions 11794 m map[string]*booleanReduceFloatPoint 11795 points []FloatPoint 11796 } 11797 11798 // newBooleanStreamFloatIterator returns a new instance of booleanStreamFloatIterator. 11799 func newBooleanStreamFloatIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, FloatPointEmitter), opt IteratorOptions) *booleanStreamFloatIterator { 11800 return &booleanStreamFloatIterator{ 11801 input: newBufBooleanIterator(input), 11802 create: createFn, 11803 dims: opt.GetDimensions(), 11804 opt: opt, 11805 m: make(map[string]*booleanReduceFloatPoint), 11806 } 11807 } 11808 11809 // Stats returns stats from the input iterator. 11810 func (itr *booleanStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() } 11811 11812 // Close closes the iterator and all child iterators. 11813 func (itr *booleanStreamFloatIterator) Close() error { return itr.input.Close() } 11814 11815 // Next returns the next value for the stream iterator. 11816 func (itr *booleanStreamFloatIterator) Next() (*FloatPoint, error) { 11817 // Calculate next window if we have no more points. 11818 if len(itr.points) == 0 { 11819 var err error 11820 itr.points, err = itr.reduce() 11821 if len(itr.points) == 0 { 11822 return nil, err 11823 } 11824 } 11825 11826 // Pop next point off the stack. 11827 p := &itr.points[len(itr.points)-1] 11828 itr.points = itr.points[:len(itr.points)-1] 11829 return p, nil 11830 } 11831 11832 // reduce creates and manages aggregators for every point from the input. 11833 // After aggregating a point, it always tries to emit a value using the emitter. 11834 func (itr *booleanStreamFloatIterator) reduce() ([]FloatPoint, error) { 11835 // We have already read all of the input points. 11836 if itr.m == nil { 11837 return nil, nil 11838 } 11839 11840 for { 11841 // Read next point. 11842 curr, err := itr.input.Next() 11843 if err != nil { 11844 return nil, err 11845 } else if curr == nil { 11846 // Close all of the aggregators to flush any remaining points to emit. 11847 var points []FloatPoint 11848 for _, rp := range itr.m { 11849 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 11850 if err := aggregator.Close(); err != nil { 11851 return nil, err 11852 } 11853 11854 pts := rp.Emitter.Emit() 11855 if len(pts) == 0 { 11856 continue 11857 } 11858 11859 for i := range pts { 11860 pts[i].Name = rp.Name 11861 pts[i].Tags = rp.Tags 11862 } 11863 points = append(points, pts...) 11864 } 11865 } 11866 11867 // Eliminate the aggregators and emitters. 11868 itr.m = nil 11869 return points, nil 11870 } else if curr.Nil { 11871 continue 11872 } 11873 tags := curr.Tags.Subset(itr.dims) 11874 11875 id := curr.Name 11876 if len(tags.m) > 0 { 11877 id += "\x00" + tags.ID() 11878 } 11879 11880 // Retrieve the aggregator for this name/tag combination or create one. 11881 rp := itr.m[id] 11882 if rp == nil { 11883 aggregator, emitter := itr.create() 11884 rp = &booleanReduceFloatPoint{ 11885 Name: curr.Name, 11886 Tags: tags, 11887 Aggregator: aggregator, 11888 Emitter: emitter, 11889 } 11890 itr.m[id] = rp 11891 } 11892 rp.Aggregator.AggregateBoolean(curr) 11893 11894 // Attempt to emit points from the aggregator. 11895 points := rp.Emitter.Emit() 11896 if len(points) == 0 { 11897 continue 11898 } 11899 11900 for i := range points { 11901 points[i].Name = rp.Name 11902 points[i].Tags = rp.Tags 11903 } 11904 return points, nil 11905 } 11906 } 11907 11908 // booleanReduceIntegerIterator executes a reducer for every interval and buffers the result. 11909 type booleanReduceIntegerIterator struct { 11910 input *bufBooleanIterator 11911 create func() (BooleanPointAggregator, IntegerPointEmitter) 11912 dims []string 11913 opt IteratorOptions 11914 points []IntegerPoint 11915 keepTags bool 11916 } 11917 11918 func newBooleanReduceIntegerIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, IntegerPointEmitter)) *booleanReduceIntegerIterator { 11919 return &booleanReduceIntegerIterator{ 11920 input: newBufBooleanIterator(input), 11921 create: createFn, 11922 dims: opt.GetDimensions(), 11923 opt: opt, 11924 } 11925 } 11926 11927 // Stats returns stats from the input iterator. 11928 func (itr *booleanReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() } 11929 11930 // Close closes the iterator and all child iterators. 11931 func (itr *booleanReduceIntegerIterator) Close() error { return itr.input.Close() } 11932 11933 // Next returns the minimum value for the next available interval. 11934 func (itr *booleanReduceIntegerIterator) Next() (*IntegerPoint, error) { 11935 // Calculate next window if we have no more points. 11936 if len(itr.points) == 0 { 11937 var err error 11938 itr.points, err = itr.reduce() 11939 if len(itr.points) == 0 { 11940 return nil, err 11941 } 11942 } 11943 11944 // Pop next point off the stack. 11945 p := &itr.points[len(itr.points)-1] 11946 itr.points = itr.points[:len(itr.points)-1] 11947 return p, nil 11948 } 11949 11950 // booleanReduceIntegerPoint stores the reduced data for a name/tag combination. 11951 type booleanReduceIntegerPoint struct { 11952 Name string 11953 Tags Tags 11954 Aggregator BooleanPointAggregator 11955 Emitter IntegerPointEmitter 11956 } 11957 11958 // reduce executes fn once for every point in the next window. 11959 // The previous value for the dimension is passed to fn. 11960 func (itr *booleanReduceIntegerIterator) reduce() ([]IntegerPoint, error) { 11961 // Calculate next window. 11962 var ( 11963 startTime, endTime int64 11964 window struct { 11965 name string 11966 tags string 11967 } 11968 ) 11969 for { 11970 p, err := itr.input.Next() 11971 if err != nil || p == nil { 11972 return nil, err 11973 } else if p.Nil { 11974 continue 11975 } 11976 11977 // Unread the point so it can be processed. 11978 itr.input.unread(p) 11979 startTime, endTime = itr.opt.Window(p.Time) 11980 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 11981 break 11982 } 11983 11984 // Create points by tags. 11985 m := make(map[string]*booleanReduceIntegerPoint) 11986 for { 11987 // Read next point. 11988 curr, err := itr.input.NextInWindow(startTime, endTime) 11989 if err != nil { 11990 return nil, err 11991 } else if curr == nil { 11992 break 11993 } else if curr.Nil { 11994 continue 11995 } else if curr.Name != window.name { 11996 itr.input.unread(curr) 11997 break 11998 } 11999 12000 // Ensure this point is within the same final window. 12001 if curr.Name != window.name { 12002 itr.input.unread(curr) 12003 break 12004 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 12005 itr.input.unread(curr) 12006 break 12007 } 12008 12009 // Retrieve the tags on this point for this level of the query. 12010 // This may be different than the bucket dimensions. 12011 tags := curr.Tags.Subset(itr.dims) 12012 id := tags.ID() 12013 12014 // Retrieve the aggregator for this name/tag combination or create one. 12015 rp := m[id] 12016 if rp == nil { 12017 aggregator, emitter := itr.create() 12018 rp = &booleanReduceIntegerPoint{ 12019 Name: curr.Name, 12020 Tags: tags, 12021 Aggregator: aggregator, 12022 Emitter: emitter, 12023 } 12024 m[id] = rp 12025 } 12026 rp.Aggregator.AggregateBoolean(curr) 12027 } 12028 12029 keys := make([]string, 0, len(m)) 12030 for k := range m { 12031 keys = append(keys, k) 12032 } 12033 12034 // Reverse sort points by name & tag. 12035 // This ensures a consistent order of output. 12036 if len(keys) > 0 { 12037 var sorted sort.Interface = sort.StringSlice(keys) 12038 if itr.opt.Ascending { 12039 sorted = sort.Reverse(sorted) 12040 } 12041 sort.Sort(sorted) 12042 } 12043 12044 // Assume the points are already sorted until proven otherwise. 12045 sortedByTime := true 12046 // Emit the points for each name & tag combination. 12047 a := make([]IntegerPoint, 0, len(m)) 12048 for _, k := range keys { 12049 rp := m[k] 12050 points := rp.Emitter.Emit() 12051 for i := len(points) - 1; i >= 0; i-- { 12052 points[i].Name = rp.Name 12053 if !itr.keepTags { 12054 points[i].Tags = rp.Tags 12055 } 12056 // Set the points time to the interval time if the reducer didn't provide one. 12057 if points[i].Time == ZeroTime { 12058 points[i].Time = startTime 12059 } else { 12060 sortedByTime = false 12061 } 12062 a = append(a, points[i]) 12063 } 12064 } 12065 // Points may be out of order. Perform a stable sort by time if requested. 12066 if !sortedByTime && itr.opt.Ordered { 12067 var sorted sort.Interface = integerPointsByTime(a) 12068 if itr.opt.Ascending { 12069 sorted = sort.Reverse(sorted) 12070 } 12071 sort.Stable(sorted) 12072 } 12073 return a, nil 12074 } 12075 12076 // booleanStreamIntegerIterator streams inputs into the iterator and emits points gradually. 12077 type booleanStreamIntegerIterator struct { 12078 input *bufBooleanIterator 12079 create func() (BooleanPointAggregator, IntegerPointEmitter) 12080 dims []string 12081 opt IteratorOptions 12082 m map[string]*booleanReduceIntegerPoint 12083 points []IntegerPoint 12084 } 12085 12086 // newBooleanStreamIntegerIterator returns a new instance of booleanStreamIntegerIterator. 12087 func newBooleanStreamIntegerIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, IntegerPointEmitter), opt IteratorOptions) *booleanStreamIntegerIterator { 12088 return &booleanStreamIntegerIterator{ 12089 input: newBufBooleanIterator(input), 12090 create: createFn, 12091 dims: opt.GetDimensions(), 12092 opt: opt, 12093 m: make(map[string]*booleanReduceIntegerPoint), 12094 } 12095 } 12096 12097 // Stats returns stats from the input iterator. 12098 func (itr *booleanStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() } 12099 12100 // Close closes the iterator and all child iterators. 12101 func (itr *booleanStreamIntegerIterator) Close() error { return itr.input.Close() } 12102 12103 // Next returns the next value for the stream iterator. 12104 func (itr *booleanStreamIntegerIterator) Next() (*IntegerPoint, error) { 12105 // Calculate next window if we have no more points. 12106 if len(itr.points) == 0 { 12107 var err error 12108 itr.points, err = itr.reduce() 12109 if len(itr.points) == 0 { 12110 return nil, err 12111 } 12112 } 12113 12114 // Pop next point off the stack. 12115 p := &itr.points[len(itr.points)-1] 12116 itr.points = itr.points[:len(itr.points)-1] 12117 return p, nil 12118 } 12119 12120 // reduce creates and manages aggregators for every point from the input. 12121 // After aggregating a point, it always tries to emit a value using the emitter. 12122 func (itr *booleanStreamIntegerIterator) reduce() ([]IntegerPoint, error) { 12123 // We have already read all of the input points. 12124 if itr.m == nil { 12125 return nil, nil 12126 } 12127 12128 for { 12129 // Read next point. 12130 curr, err := itr.input.Next() 12131 if err != nil { 12132 return nil, err 12133 } else if curr == nil { 12134 // Close all of the aggregators to flush any remaining points to emit. 12135 var points []IntegerPoint 12136 for _, rp := range itr.m { 12137 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 12138 if err := aggregator.Close(); err != nil { 12139 return nil, err 12140 } 12141 12142 pts := rp.Emitter.Emit() 12143 if len(pts) == 0 { 12144 continue 12145 } 12146 12147 for i := range pts { 12148 pts[i].Name = rp.Name 12149 pts[i].Tags = rp.Tags 12150 } 12151 points = append(points, pts...) 12152 } 12153 } 12154 12155 // Eliminate the aggregators and emitters. 12156 itr.m = nil 12157 return points, nil 12158 } else if curr.Nil { 12159 continue 12160 } 12161 tags := curr.Tags.Subset(itr.dims) 12162 12163 id := curr.Name 12164 if len(tags.m) > 0 { 12165 id += "\x00" + tags.ID() 12166 } 12167 12168 // Retrieve the aggregator for this name/tag combination or create one. 12169 rp := itr.m[id] 12170 if rp == nil { 12171 aggregator, emitter := itr.create() 12172 rp = &booleanReduceIntegerPoint{ 12173 Name: curr.Name, 12174 Tags: tags, 12175 Aggregator: aggregator, 12176 Emitter: emitter, 12177 } 12178 itr.m[id] = rp 12179 } 12180 rp.Aggregator.AggregateBoolean(curr) 12181 12182 // Attempt to emit points from the aggregator. 12183 points := rp.Emitter.Emit() 12184 if len(points) == 0 { 12185 continue 12186 } 12187 12188 for i := range points { 12189 points[i].Name = rp.Name 12190 points[i].Tags = rp.Tags 12191 } 12192 return points, nil 12193 } 12194 } 12195 12196 // booleanReduceUnsignedIterator executes a reducer for every interval and buffers the result. 12197 type booleanReduceUnsignedIterator struct { 12198 input *bufBooleanIterator 12199 create func() (BooleanPointAggregator, UnsignedPointEmitter) 12200 dims []string 12201 opt IteratorOptions 12202 points []UnsignedPoint 12203 keepTags bool 12204 } 12205 12206 func newBooleanReduceUnsignedIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, UnsignedPointEmitter)) *booleanReduceUnsignedIterator { 12207 return &booleanReduceUnsignedIterator{ 12208 input: newBufBooleanIterator(input), 12209 create: createFn, 12210 dims: opt.GetDimensions(), 12211 opt: opt, 12212 } 12213 } 12214 12215 // Stats returns stats from the input iterator. 12216 func (itr *booleanReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() } 12217 12218 // Close closes the iterator and all child iterators. 12219 func (itr *booleanReduceUnsignedIterator) Close() error { return itr.input.Close() } 12220 12221 // Next returns the minimum value for the next available interval. 12222 func (itr *booleanReduceUnsignedIterator) Next() (*UnsignedPoint, error) { 12223 // Calculate next window if we have no more points. 12224 if len(itr.points) == 0 { 12225 var err error 12226 itr.points, err = itr.reduce() 12227 if len(itr.points) == 0 { 12228 return nil, err 12229 } 12230 } 12231 12232 // Pop next point off the stack. 12233 p := &itr.points[len(itr.points)-1] 12234 itr.points = itr.points[:len(itr.points)-1] 12235 return p, nil 12236 } 12237 12238 // booleanReduceUnsignedPoint stores the reduced data for a name/tag combination. 12239 type booleanReduceUnsignedPoint struct { 12240 Name string 12241 Tags Tags 12242 Aggregator BooleanPointAggregator 12243 Emitter UnsignedPointEmitter 12244 } 12245 12246 // reduce executes fn once for every point in the next window. 12247 // The previous value for the dimension is passed to fn. 12248 func (itr *booleanReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) { 12249 // Calculate next window. 12250 var ( 12251 startTime, endTime int64 12252 window struct { 12253 name string 12254 tags string 12255 } 12256 ) 12257 for { 12258 p, err := itr.input.Next() 12259 if err != nil || p == nil { 12260 return nil, err 12261 } else if p.Nil { 12262 continue 12263 } 12264 12265 // Unread the point so it can be processed. 12266 itr.input.unread(p) 12267 startTime, endTime = itr.opt.Window(p.Time) 12268 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 12269 break 12270 } 12271 12272 // Create points by tags. 12273 m := make(map[string]*booleanReduceUnsignedPoint) 12274 for { 12275 // Read next point. 12276 curr, err := itr.input.NextInWindow(startTime, endTime) 12277 if err != nil { 12278 return nil, err 12279 } else if curr == nil { 12280 break 12281 } else if curr.Nil { 12282 continue 12283 } else if curr.Name != window.name { 12284 itr.input.unread(curr) 12285 break 12286 } 12287 12288 // Ensure this point is within the same final window. 12289 if curr.Name != window.name { 12290 itr.input.unread(curr) 12291 break 12292 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 12293 itr.input.unread(curr) 12294 break 12295 } 12296 12297 // Retrieve the tags on this point for this level of the query. 12298 // This may be different than the bucket dimensions. 12299 tags := curr.Tags.Subset(itr.dims) 12300 id := tags.ID() 12301 12302 // Retrieve the aggregator for this name/tag combination or create one. 12303 rp := m[id] 12304 if rp == nil { 12305 aggregator, emitter := itr.create() 12306 rp = &booleanReduceUnsignedPoint{ 12307 Name: curr.Name, 12308 Tags: tags, 12309 Aggregator: aggregator, 12310 Emitter: emitter, 12311 } 12312 m[id] = rp 12313 } 12314 rp.Aggregator.AggregateBoolean(curr) 12315 } 12316 12317 keys := make([]string, 0, len(m)) 12318 for k := range m { 12319 keys = append(keys, k) 12320 } 12321 12322 // Reverse sort points by name & tag. 12323 // This ensures a consistent order of output. 12324 if len(keys) > 0 { 12325 var sorted sort.Interface = sort.StringSlice(keys) 12326 if itr.opt.Ascending { 12327 sorted = sort.Reverse(sorted) 12328 } 12329 sort.Sort(sorted) 12330 } 12331 12332 // Assume the points are already sorted until proven otherwise. 12333 sortedByTime := true 12334 // Emit the points for each name & tag combination. 12335 a := make([]UnsignedPoint, 0, len(m)) 12336 for _, k := range keys { 12337 rp := m[k] 12338 points := rp.Emitter.Emit() 12339 for i := len(points) - 1; i >= 0; i-- { 12340 points[i].Name = rp.Name 12341 if !itr.keepTags { 12342 points[i].Tags = rp.Tags 12343 } 12344 // Set the points time to the interval time if the reducer didn't provide one. 12345 if points[i].Time == ZeroTime { 12346 points[i].Time = startTime 12347 } else { 12348 sortedByTime = false 12349 } 12350 a = append(a, points[i]) 12351 } 12352 } 12353 // Points may be out of order. Perform a stable sort by time if requested. 12354 if !sortedByTime && itr.opt.Ordered { 12355 var sorted sort.Interface = unsignedPointsByTime(a) 12356 if itr.opt.Ascending { 12357 sorted = sort.Reverse(sorted) 12358 } 12359 sort.Stable(sorted) 12360 } 12361 return a, nil 12362 } 12363 12364 // booleanStreamUnsignedIterator streams inputs into the iterator and emits points gradually. 12365 type booleanStreamUnsignedIterator struct { 12366 input *bufBooleanIterator 12367 create func() (BooleanPointAggregator, UnsignedPointEmitter) 12368 dims []string 12369 opt IteratorOptions 12370 m map[string]*booleanReduceUnsignedPoint 12371 points []UnsignedPoint 12372 } 12373 12374 // newBooleanStreamUnsignedIterator returns a new instance of booleanStreamUnsignedIterator. 12375 func newBooleanStreamUnsignedIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *booleanStreamUnsignedIterator { 12376 return &booleanStreamUnsignedIterator{ 12377 input: newBufBooleanIterator(input), 12378 create: createFn, 12379 dims: opt.GetDimensions(), 12380 opt: opt, 12381 m: make(map[string]*booleanReduceUnsignedPoint), 12382 } 12383 } 12384 12385 // Stats returns stats from the input iterator. 12386 func (itr *booleanStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() } 12387 12388 // Close closes the iterator and all child iterators. 12389 func (itr *booleanStreamUnsignedIterator) Close() error { return itr.input.Close() } 12390 12391 // Next returns the next value for the stream iterator. 12392 func (itr *booleanStreamUnsignedIterator) Next() (*UnsignedPoint, error) { 12393 // Calculate next window if we have no more points. 12394 if len(itr.points) == 0 { 12395 var err error 12396 itr.points, err = itr.reduce() 12397 if len(itr.points) == 0 { 12398 return nil, err 12399 } 12400 } 12401 12402 // Pop next point off the stack. 12403 p := &itr.points[len(itr.points)-1] 12404 itr.points = itr.points[:len(itr.points)-1] 12405 return p, nil 12406 } 12407 12408 // reduce creates and manages aggregators for every point from the input. 12409 // After aggregating a point, it always tries to emit a value using the emitter. 12410 func (itr *booleanStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) { 12411 // We have already read all of the input points. 12412 if itr.m == nil { 12413 return nil, nil 12414 } 12415 12416 for { 12417 // Read next point. 12418 curr, err := itr.input.Next() 12419 if err != nil { 12420 return nil, err 12421 } else if curr == nil { 12422 // Close all of the aggregators to flush any remaining points to emit. 12423 var points []UnsignedPoint 12424 for _, rp := range itr.m { 12425 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 12426 if err := aggregator.Close(); err != nil { 12427 return nil, err 12428 } 12429 12430 pts := rp.Emitter.Emit() 12431 if len(pts) == 0 { 12432 continue 12433 } 12434 12435 for i := range pts { 12436 pts[i].Name = rp.Name 12437 pts[i].Tags = rp.Tags 12438 } 12439 points = append(points, pts...) 12440 } 12441 } 12442 12443 // Eliminate the aggregators and emitters. 12444 itr.m = nil 12445 return points, nil 12446 } else if curr.Nil { 12447 continue 12448 } 12449 tags := curr.Tags.Subset(itr.dims) 12450 12451 id := curr.Name 12452 if len(tags.m) > 0 { 12453 id += "\x00" + tags.ID() 12454 } 12455 12456 // Retrieve the aggregator for this name/tag combination or create one. 12457 rp := itr.m[id] 12458 if rp == nil { 12459 aggregator, emitter := itr.create() 12460 rp = &booleanReduceUnsignedPoint{ 12461 Name: curr.Name, 12462 Tags: tags, 12463 Aggregator: aggregator, 12464 Emitter: emitter, 12465 } 12466 itr.m[id] = rp 12467 } 12468 rp.Aggregator.AggregateBoolean(curr) 12469 12470 // Attempt to emit points from the aggregator. 12471 points := rp.Emitter.Emit() 12472 if len(points) == 0 { 12473 continue 12474 } 12475 12476 for i := range points { 12477 points[i].Name = rp.Name 12478 points[i].Tags = rp.Tags 12479 } 12480 return points, nil 12481 } 12482 } 12483 12484 // booleanReduceStringIterator executes a reducer for every interval and buffers the result. 12485 type booleanReduceStringIterator struct { 12486 input *bufBooleanIterator 12487 create func() (BooleanPointAggregator, StringPointEmitter) 12488 dims []string 12489 opt IteratorOptions 12490 points []StringPoint 12491 keepTags bool 12492 } 12493 12494 func newBooleanReduceStringIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, StringPointEmitter)) *booleanReduceStringIterator { 12495 return &booleanReduceStringIterator{ 12496 input: newBufBooleanIterator(input), 12497 create: createFn, 12498 dims: opt.GetDimensions(), 12499 opt: opt, 12500 } 12501 } 12502 12503 // Stats returns stats from the input iterator. 12504 func (itr *booleanReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() } 12505 12506 // Close closes the iterator and all child iterators. 12507 func (itr *booleanReduceStringIterator) Close() error { return itr.input.Close() } 12508 12509 // Next returns the minimum value for the next available interval. 12510 func (itr *booleanReduceStringIterator) Next() (*StringPoint, error) { 12511 // Calculate next window if we have no more points. 12512 if len(itr.points) == 0 { 12513 var err error 12514 itr.points, err = itr.reduce() 12515 if len(itr.points) == 0 { 12516 return nil, err 12517 } 12518 } 12519 12520 // Pop next point off the stack. 12521 p := &itr.points[len(itr.points)-1] 12522 itr.points = itr.points[:len(itr.points)-1] 12523 return p, nil 12524 } 12525 12526 // booleanReduceStringPoint stores the reduced data for a name/tag combination. 12527 type booleanReduceStringPoint struct { 12528 Name string 12529 Tags Tags 12530 Aggregator BooleanPointAggregator 12531 Emitter StringPointEmitter 12532 } 12533 12534 // reduce executes fn once for every point in the next window. 12535 // The previous value for the dimension is passed to fn. 12536 func (itr *booleanReduceStringIterator) reduce() ([]StringPoint, error) { 12537 // Calculate next window. 12538 var ( 12539 startTime, endTime int64 12540 window struct { 12541 name string 12542 tags string 12543 } 12544 ) 12545 for { 12546 p, err := itr.input.Next() 12547 if err != nil || p == nil { 12548 return nil, err 12549 } else if p.Nil { 12550 continue 12551 } 12552 12553 // Unread the point so it can be processed. 12554 itr.input.unread(p) 12555 startTime, endTime = itr.opt.Window(p.Time) 12556 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 12557 break 12558 } 12559 12560 // Create points by tags. 12561 m := make(map[string]*booleanReduceStringPoint) 12562 for { 12563 // Read next point. 12564 curr, err := itr.input.NextInWindow(startTime, endTime) 12565 if err != nil { 12566 return nil, err 12567 } else if curr == nil { 12568 break 12569 } else if curr.Nil { 12570 continue 12571 } else if curr.Name != window.name { 12572 itr.input.unread(curr) 12573 break 12574 } 12575 12576 // Ensure this point is within the same final window. 12577 if curr.Name != window.name { 12578 itr.input.unread(curr) 12579 break 12580 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 12581 itr.input.unread(curr) 12582 break 12583 } 12584 12585 // Retrieve the tags on this point for this level of the query. 12586 // This may be different than the bucket dimensions. 12587 tags := curr.Tags.Subset(itr.dims) 12588 id := tags.ID() 12589 12590 // Retrieve the aggregator for this name/tag combination or create one. 12591 rp := m[id] 12592 if rp == nil { 12593 aggregator, emitter := itr.create() 12594 rp = &booleanReduceStringPoint{ 12595 Name: curr.Name, 12596 Tags: tags, 12597 Aggregator: aggregator, 12598 Emitter: emitter, 12599 } 12600 m[id] = rp 12601 } 12602 rp.Aggregator.AggregateBoolean(curr) 12603 } 12604 12605 keys := make([]string, 0, len(m)) 12606 for k := range m { 12607 keys = append(keys, k) 12608 } 12609 12610 // Reverse sort points by name & tag. 12611 // This ensures a consistent order of output. 12612 if len(keys) > 0 { 12613 var sorted sort.Interface = sort.StringSlice(keys) 12614 if itr.opt.Ascending { 12615 sorted = sort.Reverse(sorted) 12616 } 12617 sort.Sort(sorted) 12618 } 12619 12620 // Assume the points are already sorted until proven otherwise. 12621 sortedByTime := true 12622 // Emit the points for each name & tag combination. 12623 a := make([]StringPoint, 0, len(m)) 12624 for _, k := range keys { 12625 rp := m[k] 12626 points := rp.Emitter.Emit() 12627 for i := len(points) - 1; i >= 0; i-- { 12628 points[i].Name = rp.Name 12629 if !itr.keepTags { 12630 points[i].Tags = rp.Tags 12631 } 12632 // Set the points time to the interval time if the reducer didn't provide one. 12633 if points[i].Time == ZeroTime { 12634 points[i].Time = startTime 12635 } else { 12636 sortedByTime = false 12637 } 12638 a = append(a, points[i]) 12639 } 12640 } 12641 // Points may be out of order. Perform a stable sort by time if requested. 12642 if !sortedByTime && itr.opt.Ordered { 12643 var sorted sort.Interface = stringPointsByTime(a) 12644 if itr.opt.Ascending { 12645 sorted = sort.Reverse(sorted) 12646 } 12647 sort.Stable(sorted) 12648 } 12649 return a, nil 12650 } 12651 12652 // booleanStreamStringIterator streams inputs into the iterator and emits points gradually. 12653 type booleanStreamStringIterator struct { 12654 input *bufBooleanIterator 12655 create func() (BooleanPointAggregator, StringPointEmitter) 12656 dims []string 12657 opt IteratorOptions 12658 m map[string]*booleanReduceStringPoint 12659 points []StringPoint 12660 } 12661 12662 // newBooleanStreamStringIterator returns a new instance of booleanStreamStringIterator. 12663 func newBooleanStreamStringIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, StringPointEmitter), opt IteratorOptions) *booleanStreamStringIterator { 12664 return &booleanStreamStringIterator{ 12665 input: newBufBooleanIterator(input), 12666 create: createFn, 12667 dims: opt.GetDimensions(), 12668 opt: opt, 12669 m: make(map[string]*booleanReduceStringPoint), 12670 } 12671 } 12672 12673 // Stats returns stats from the input iterator. 12674 func (itr *booleanStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() } 12675 12676 // Close closes the iterator and all child iterators. 12677 func (itr *booleanStreamStringIterator) Close() error { return itr.input.Close() } 12678 12679 // Next returns the next value for the stream iterator. 12680 func (itr *booleanStreamStringIterator) Next() (*StringPoint, error) { 12681 // Calculate next window if we have no more points. 12682 if len(itr.points) == 0 { 12683 var err error 12684 itr.points, err = itr.reduce() 12685 if len(itr.points) == 0 { 12686 return nil, err 12687 } 12688 } 12689 12690 // Pop next point off the stack. 12691 p := &itr.points[len(itr.points)-1] 12692 itr.points = itr.points[:len(itr.points)-1] 12693 return p, nil 12694 } 12695 12696 // reduce creates and manages aggregators for every point from the input. 12697 // After aggregating a point, it always tries to emit a value using the emitter. 12698 func (itr *booleanStreamStringIterator) reduce() ([]StringPoint, error) { 12699 // We have already read all of the input points. 12700 if itr.m == nil { 12701 return nil, nil 12702 } 12703 12704 for { 12705 // Read next point. 12706 curr, err := itr.input.Next() 12707 if err != nil { 12708 return nil, err 12709 } else if curr == nil { 12710 // Close all of the aggregators to flush any remaining points to emit. 12711 var points []StringPoint 12712 for _, rp := range itr.m { 12713 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 12714 if err := aggregator.Close(); err != nil { 12715 return nil, err 12716 } 12717 12718 pts := rp.Emitter.Emit() 12719 if len(pts) == 0 { 12720 continue 12721 } 12722 12723 for i := range pts { 12724 pts[i].Name = rp.Name 12725 pts[i].Tags = rp.Tags 12726 } 12727 points = append(points, pts...) 12728 } 12729 } 12730 12731 // Eliminate the aggregators and emitters. 12732 itr.m = nil 12733 return points, nil 12734 } else if curr.Nil { 12735 continue 12736 } 12737 tags := curr.Tags.Subset(itr.dims) 12738 12739 id := curr.Name 12740 if len(tags.m) > 0 { 12741 id += "\x00" + tags.ID() 12742 } 12743 12744 // Retrieve the aggregator for this name/tag combination or create one. 12745 rp := itr.m[id] 12746 if rp == nil { 12747 aggregator, emitter := itr.create() 12748 rp = &booleanReduceStringPoint{ 12749 Name: curr.Name, 12750 Tags: tags, 12751 Aggregator: aggregator, 12752 Emitter: emitter, 12753 } 12754 itr.m[id] = rp 12755 } 12756 rp.Aggregator.AggregateBoolean(curr) 12757 12758 // Attempt to emit points from the aggregator. 12759 points := rp.Emitter.Emit() 12760 if len(points) == 0 { 12761 continue 12762 } 12763 12764 for i := range points { 12765 points[i].Name = rp.Name 12766 points[i].Tags = rp.Tags 12767 } 12768 return points, nil 12769 } 12770 } 12771 12772 // booleanReduceBooleanIterator executes a reducer for every interval and buffers the result. 12773 type booleanReduceBooleanIterator struct { 12774 input *bufBooleanIterator 12775 create func() (BooleanPointAggregator, BooleanPointEmitter) 12776 dims []string 12777 opt IteratorOptions 12778 points []BooleanPoint 12779 keepTags bool 12780 } 12781 12782 func newBooleanReduceBooleanIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, BooleanPointEmitter)) *booleanReduceBooleanIterator { 12783 return &booleanReduceBooleanIterator{ 12784 input: newBufBooleanIterator(input), 12785 create: createFn, 12786 dims: opt.GetDimensions(), 12787 opt: opt, 12788 } 12789 } 12790 12791 // Stats returns stats from the input iterator. 12792 func (itr *booleanReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() } 12793 12794 // Close closes the iterator and all child iterators. 12795 func (itr *booleanReduceBooleanIterator) Close() error { return itr.input.Close() } 12796 12797 // Next returns the minimum value for the next available interval. 12798 func (itr *booleanReduceBooleanIterator) Next() (*BooleanPoint, error) { 12799 // Calculate next window if we have no more points. 12800 if len(itr.points) == 0 { 12801 var err error 12802 itr.points, err = itr.reduce() 12803 if len(itr.points) == 0 { 12804 return nil, err 12805 } 12806 } 12807 12808 // Pop next point off the stack. 12809 p := &itr.points[len(itr.points)-1] 12810 itr.points = itr.points[:len(itr.points)-1] 12811 return p, nil 12812 } 12813 12814 // booleanReduceBooleanPoint stores the reduced data for a name/tag combination. 12815 type booleanReduceBooleanPoint struct { 12816 Name string 12817 Tags Tags 12818 Aggregator BooleanPointAggregator 12819 Emitter BooleanPointEmitter 12820 } 12821 12822 // reduce executes fn once for every point in the next window. 12823 // The previous value for the dimension is passed to fn. 12824 func (itr *booleanReduceBooleanIterator) reduce() ([]BooleanPoint, error) { 12825 // Calculate next window. 12826 var ( 12827 startTime, endTime int64 12828 window struct { 12829 name string 12830 tags string 12831 } 12832 ) 12833 for { 12834 p, err := itr.input.Next() 12835 if err != nil || p == nil { 12836 return nil, err 12837 } else if p.Nil { 12838 continue 12839 } 12840 12841 // Unread the point so it can be processed. 12842 itr.input.unread(p) 12843 startTime, endTime = itr.opt.Window(p.Time) 12844 window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID() 12845 break 12846 } 12847 12848 // Create points by tags. 12849 m := make(map[string]*booleanReduceBooleanPoint) 12850 for { 12851 // Read next point. 12852 curr, err := itr.input.NextInWindow(startTime, endTime) 12853 if err != nil { 12854 return nil, err 12855 } else if curr == nil { 12856 break 12857 } else if curr.Nil { 12858 continue 12859 } else if curr.Name != window.name { 12860 itr.input.unread(curr) 12861 break 12862 } 12863 12864 // Ensure this point is within the same final window. 12865 if curr.Name != window.name { 12866 itr.input.unread(curr) 12867 break 12868 } else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags { 12869 itr.input.unread(curr) 12870 break 12871 } 12872 12873 // Retrieve the tags on this point for this level of the query. 12874 // This may be different than the bucket dimensions. 12875 tags := curr.Tags.Subset(itr.dims) 12876 id := tags.ID() 12877 12878 // Retrieve the aggregator for this name/tag combination or create one. 12879 rp := m[id] 12880 if rp == nil { 12881 aggregator, emitter := itr.create() 12882 rp = &booleanReduceBooleanPoint{ 12883 Name: curr.Name, 12884 Tags: tags, 12885 Aggregator: aggregator, 12886 Emitter: emitter, 12887 } 12888 m[id] = rp 12889 } 12890 rp.Aggregator.AggregateBoolean(curr) 12891 } 12892 12893 keys := make([]string, 0, len(m)) 12894 for k := range m { 12895 keys = append(keys, k) 12896 } 12897 12898 // Reverse sort points by name & tag. 12899 // This ensures a consistent order of output. 12900 if len(keys) > 0 { 12901 var sorted sort.Interface = sort.StringSlice(keys) 12902 if itr.opt.Ascending { 12903 sorted = sort.Reverse(sorted) 12904 } 12905 sort.Sort(sorted) 12906 } 12907 12908 // Assume the points are already sorted until proven otherwise. 12909 sortedByTime := true 12910 // Emit the points for each name & tag combination. 12911 a := make([]BooleanPoint, 0, len(m)) 12912 for _, k := range keys { 12913 rp := m[k] 12914 points := rp.Emitter.Emit() 12915 for i := len(points) - 1; i >= 0; i-- { 12916 points[i].Name = rp.Name 12917 if !itr.keepTags { 12918 points[i].Tags = rp.Tags 12919 } 12920 // Set the points time to the interval time if the reducer didn't provide one. 12921 if points[i].Time == ZeroTime { 12922 points[i].Time = startTime 12923 } else { 12924 sortedByTime = false 12925 } 12926 a = append(a, points[i]) 12927 } 12928 } 12929 // Points may be out of order. Perform a stable sort by time if requested. 12930 if !sortedByTime && itr.opt.Ordered { 12931 var sorted sort.Interface = booleanPointsByTime(a) 12932 if itr.opt.Ascending { 12933 sorted = sort.Reverse(sorted) 12934 } 12935 sort.Stable(sorted) 12936 } 12937 return a, nil 12938 } 12939 12940 // booleanStreamBooleanIterator streams inputs into the iterator and emits points gradually. 12941 type booleanStreamBooleanIterator struct { 12942 input *bufBooleanIterator 12943 create func() (BooleanPointAggregator, BooleanPointEmitter) 12944 dims []string 12945 opt IteratorOptions 12946 m map[string]*booleanReduceBooleanPoint 12947 points []BooleanPoint 12948 } 12949 12950 // newBooleanStreamBooleanIterator returns a new instance of booleanStreamBooleanIterator. 12951 func newBooleanStreamBooleanIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, BooleanPointEmitter), opt IteratorOptions) *booleanStreamBooleanIterator { 12952 return &booleanStreamBooleanIterator{ 12953 input: newBufBooleanIterator(input), 12954 create: createFn, 12955 dims: opt.GetDimensions(), 12956 opt: opt, 12957 m: make(map[string]*booleanReduceBooleanPoint), 12958 } 12959 } 12960 12961 // Stats returns stats from the input iterator. 12962 func (itr *booleanStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() } 12963 12964 // Close closes the iterator and all child iterators. 12965 func (itr *booleanStreamBooleanIterator) Close() error { return itr.input.Close() } 12966 12967 // Next returns the next value for the stream iterator. 12968 func (itr *booleanStreamBooleanIterator) Next() (*BooleanPoint, error) { 12969 // Calculate next window if we have no more points. 12970 if len(itr.points) == 0 { 12971 var err error 12972 itr.points, err = itr.reduce() 12973 if len(itr.points) == 0 { 12974 return nil, err 12975 } 12976 } 12977 12978 // Pop next point off the stack. 12979 p := &itr.points[len(itr.points)-1] 12980 itr.points = itr.points[:len(itr.points)-1] 12981 return p, nil 12982 } 12983 12984 // reduce creates and manages aggregators for every point from the input. 12985 // After aggregating a point, it always tries to emit a value using the emitter. 12986 func (itr *booleanStreamBooleanIterator) reduce() ([]BooleanPoint, error) { 12987 // We have already read all of the input points. 12988 if itr.m == nil { 12989 return nil, nil 12990 } 12991 12992 for { 12993 // Read next point. 12994 curr, err := itr.input.Next() 12995 if err != nil { 12996 return nil, err 12997 } else if curr == nil { 12998 // Close all of the aggregators to flush any remaining points to emit. 12999 var points []BooleanPoint 13000 for _, rp := range itr.m { 13001 if aggregator, ok := rp.Aggregator.(io.Closer); ok { 13002 if err := aggregator.Close(); err != nil { 13003 return nil, err 13004 } 13005 13006 pts := rp.Emitter.Emit() 13007 if len(pts) == 0 { 13008 continue 13009 } 13010 13011 for i := range pts { 13012 pts[i].Name = rp.Name 13013 pts[i].Tags = rp.Tags 13014 } 13015 points = append(points, pts...) 13016 } 13017 } 13018 13019 // Eliminate the aggregators and emitters. 13020 itr.m = nil 13021 return points, nil 13022 } else if curr.Nil { 13023 continue 13024 } 13025 tags := curr.Tags.Subset(itr.dims) 13026 13027 id := curr.Name 13028 if len(tags.m) > 0 { 13029 id += "\x00" + tags.ID() 13030 } 13031 13032 // Retrieve the aggregator for this name/tag combination or create one. 13033 rp := itr.m[id] 13034 if rp == nil { 13035 aggregator, emitter := itr.create() 13036 rp = &booleanReduceBooleanPoint{ 13037 Name: curr.Name, 13038 Tags: tags, 13039 Aggregator: aggregator, 13040 Emitter: emitter, 13041 } 13042 itr.m[id] = rp 13043 } 13044 rp.Aggregator.AggregateBoolean(curr) 13045 13046 // Attempt to emit points from the aggregator. 13047 points := rp.Emitter.Emit() 13048 if len(points) == 0 { 13049 continue 13050 } 13051 13052 for i := range points { 13053 points[i].Name = rp.Name 13054 points[i].Tags = rp.Tags 13055 } 13056 return points, nil 13057 } 13058 } 13059 13060 // booleanDedupeIterator only outputs unique points. 13061 // This differs from the DistinctIterator in that it compares all aux fields too. 13062 // This iterator is relatively inefficient and should only be used on small 13063 // datasets such as meta query results. 13064 type booleanDedupeIterator struct { 13065 input BooleanIterator 13066 m map[string]struct{} // lookup of points already sent 13067 } 13068 13069 type booleanIteratorMapper struct { 13070 cur Cursor 13071 row Row 13072 driver IteratorMap // which iterator to use for the primary value, can be nil 13073 fields []IteratorMap // which iterator to use for an aux field 13074 point BooleanPoint 13075 } 13076 13077 func newBooleanIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *booleanIteratorMapper { 13078 return &booleanIteratorMapper{ 13079 cur: cur, 13080 driver: driver, 13081 fields: fields, 13082 point: BooleanPoint{ 13083 Aux: make([]interface{}, len(fields)), 13084 }, 13085 } 13086 } 13087 13088 func (itr *booleanIteratorMapper) Next() (*BooleanPoint, error) { 13089 if !itr.cur.Scan(&itr.row) { 13090 if err := itr.cur.Err(); err != nil { 13091 return nil, err 13092 } 13093 return nil, nil 13094 } 13095 13096 itr.point.Time = itr.row.Time 13097 itr.point.Name = itr.row.Series.Name 13098 itr.point.Tags = itr.row.Series.Tags 13099 13100 if itr.driver != nil { 13101 if v := itr.driver.Value(&itr.row); v != nil { 13102 if v, ok := castToBoolean(v); ok { 13103 itr.point.Value = v 13104 itr.point.Nil = false 13105 } else { 13106 itr.point.Value = false 13107 itr.point.Nil = true 13108 } 13109 } else { 13110 itr.point.Value = false 13111 itr.point.Nil = true 13112 } 13113 } 13114 for i, f := range itr.fields { 13115 itr.point.Aux[i] = f.Value(&itr.row) 13116 } 13117 return &itr.point, nil 13118 } 13119 13120 func (itr *booleanIteratorMapper) Stats() IteratorStats { 13121 return itr.cur.Stats() 13122 } 13123 13124 func (itr *booleanIteratorMapper) Close() error { 13125 return itr.cur.Close() 13126 } 13127 13128 type booleanFilterIterator struct { 13129 input BooleanIterator 13130 cond influxql.Expr 13131 opt IteratorOptions 13132 m map[string]interface{} 13133 } 13134 13135 func newBooleanFilterIterator(input BooleanIterator, cond influxql.Expr, opt IteratorOptions) BooleanIterator { 13136 // Strip out time conditions from the WHERE clause. 13137 // TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct. 13138 n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node { 13139 switch n := n.(type) { 13140 case *influxql.BinaryExpr: 13141 if n.LHS.String() == "time" { 13142 return &influxql.BooleanLiteral{Val: true} 13143 } 13144 } 13145 return n 13146 }) 13147 13148 cond, _ = n.(influxql.Expr) 13149 if cond == nil { 13150 return input 13151 } else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val { 13152 return input 13153 } 13154 13155 return &booleanFilterIterator{ 13156 input: input, 13157 cond: cond, 13158 opt: opt, 13159 m: make(map[string]interface{}), 13160 } 13161 } 13162 13163 func (itr *booleanFilterIterator) Stats() IteratorStats { return itr.input.Stats() } 13164 func (itr *booleanFilterIterator) Close() error { return itr.input.Close() } 13165 13166 func (itr *booleanFilterIterator) Next() (*BooleanPoint, error) { 13167 for { 13168 p, err := itr.input.Next() 13169 if err != nil || p == nil { 13170 return nil, err 13171 } 13172 13173 for i, ref := range itr.opt.Aux { 13174 itr.m[ref.Val] = p.Aux[i] 13175 } 13176 for k, v := range p.Tags.KeyValues() { 13177 itr.m[k] = v 13178 } 13179 13180 if !influxql.EvalBool(itr.cond, itr.m) { 13181 continue 13182 } 13183 return p, nil 13184 } 13185 } 13186 13187 type booleanTagSubsetIterator struct { 13188 input BooleanIterator 13189 point BooleanPoint 13190 lastTags Tags 13191 dimensions []string 13192 } 13193 13194 func newBooleanTagSubsetIterator(input BooleanIterator, opt IteratorOptions) *booleanTagSubsetIterator { 13195 return &booleanTagSubsetIterator{ 13196 input: input, 13197 dimensions: opt.GetDimensions(), 13198 } 13199 } 13200 13201 func (itr *booleanTagSubsetIterator) Next() (*BooleanPoint, error) { 13202 p, err := itr.input.Next() 13203 if err != nil { 13204 return nil, err 13205 } else if p == nil { 13206 return nil, nil 13207 } 13208 13209 itr.point.Name = p.Name 13210 if !p.Tags.Equal(itr.lastTags) { 13211 itr.point.Tags = p.Tags.Subset(itr.dimensions) 13212 itr.lastTags = p.Tags 13213 } 13214 itr.point.Time = p.Time 13215 itr.point.Value = p.Value 13216 itr.point.Aux = p.Aux 13217 itr.point.Aggregated = p.Aggregated 13218 itr.point.Nil = p.Nil 13219 return &itr.point, nil 13220 } 13221 13222 func (itr *booleanTagSubsetIterator) Stats() IteratorStats { 13223 return itr.input.Stats() 13224 } 13225 13226 func (itr *booleanTagSubsetIterator) Close() error { 13227 return itr.input.Close() 13228 } 13229 13230 // newBooleanDedupeIterator returns a new instance of booleanDedupeIterator. 13231 func newBooleanDedupeIterator(input BooleanIterator) *booleanDedupeIterator { 13232 return &booleanDedupeIterator{ 13233 input: input, 13234 m: make(map[string]struct{}), 13235 } 13236 } 13237 13238 // Stats returns stats from the input iterator. 13239 func (itr *booleanDedupeIterator) Stats() IteratorStats { return itr.input.Stats() } 13240 13241 // Close closes the iterator and all child iterators. 13242 func (itr *booleanDedupeIterator) Close() error { return itr.input.Close() } 13243 13244 // Next returns the next unique point from the input iterator. 13245 func (itr *booleanDedupeIterator) Next() (*BooleanPoint, error) { 13246 for { 13247 // Read next point. 13248 p, err := itr.input.Next() 13249 if p == nil || err != nil { 13250 return nil, err 13251 } 13252 13253 // Serialize to bytes to store in lookup. 13254 buf, err := proto.Marshal(encodeBooleanPoint(p)) 13255 if err != nil { 13256 return nil, err 13257 } 13258 13259 // If the point has already been output then move to the next point. 13260 if _, ok := itr.m[string(buf)]; ok { 13261 continue 13262 } 13263 13264 // Otherwise mark it as emitted and return point. 13265 itr.m[string(buf)] = struct{}{} 13266 return p, nil 13267 } 13268 } 13269 13270 // booleanReaderIterator represents an iterator that streams from a reader. 13271 type booleanReaderIterator struct { 13272 r io.Reader 13273 dec *BooleanPointDecoder 13274 } 13275 13276 // newBooleanReaderIterator returns a new instance of booleanReaderIterator. 13277 func newBooleanReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *booleanReaderIterator { 13278 dec := NewBooleanPointDecoder(ctx, r) 13279 dec.stats = stats 13280 13281 return &booleanReaderIterator{ 13282 r: r, 13283 dec: dec, 13284 } 13285 } 13286 13287 // Stats returns stats about points processed. 13288 func (itr *booleanReaderIterator) Stats() IteratorStats { return itr.dec.stats } 13289 13290 // Close closes the underlying reader, if applicable. 13291 func (itr *booleanReaderIterator) Close() error { 13292 if r, ok := itr.r.(io.ReadCloser); ok { 13293 return r.Close() 13294 } 13295 return nil 13296 } 13297 13298 // Next returns the next point from the iterator. 13299 func (itr *booleanReaderIterator) Next() (*BooleanPoint, error) { 13300 // OPTIMIZE(benbjohnson): Reuse point on iterator. 13301 13302 // Unmarshal next point. 13303 p := &BooleanPoint{} 13304 if err := itr.dec.DecodeBooleanPoint(p); err == io.EOF { 13305 return nil, nil 13306 } else if err != nil { 13307 return nil, err 13308 } 13309 return p, nil 13310 } 13311 13312 // encodeFloatIterator encodes all points from itr to the underlying writer. 13313 func (enc *IteratorEncoder) encodeFloatIterator(itr FloatIterator) error { 13314 ticker := time.NewTicker(enc.StatsInterval) 13315 defer ticker.Stop() 13316 13317 // Emit initial stats. 13318 if err := enc.encodeStats(itr.Stats()); err != nil { 13319 return err 13320 } 13321 13322 // Continually stream points from the iterator into the encoder. 13323 penc := NewFloatPointEncoder(enc.w) 13324 for { 13325 // Emit stats periodically. 13326 select { 13327 case <-ticker.C: 13328 if err := enc.encodeStats(itr.Stats()); err != nil { 13329 return err 13330 } 13331 default: 13332 } 13333 13334 // Retrieve the next point from the iterator. 13335 p, err := itr.Next() 13336 if err != nil { 13337 return err 13338 } else if p == nil { 13339 break 13340 } 13341 13342 // Write the point to the point encoder. 13343 if err := penc.EncodeFloatPoint(p); err != nil { 13344 return err 13345 } 13346 } 13347 13348 // Emit final stats. 13349 if err := enc.encodeStats(itr.Stats()); err != nil { 13350 return err 13351 } 13352 return nil 13353 } 13354 13355 // encodeIntegerIterator encodes all points from itr to the underlying writer. 13356 func (enc *IteratorEncoder) encodeIntegerIterator(itr IntegerIterator) error { 13357 ticker := time.NewTicker(enc.StatsInterval) 13358 defer ticker.Stop() 13359 13360 // Emit initial stats. 13361 if err := enc.encodeStats(itr.Stats()); err != nil { 13362 return err 13363 } 13364 13365 // Continually stream points from the iterator into the encoder. 13366 penc := NewIntegerPointEncoder(enc.w) 13367 for { 13368 // Emit stats periodically. 13369 select { 13370 case <-ticker.C: 13371 if err := enc.encodeStats(itr.Stats()); err != nil { 13372 return err 13373 } 13374 default: 13375 } 13376 13377 // Retrieve the next point from the iterator. 13378 p, err := itr.Next() 13379 if err != nil { 13380 return err 13381 } else if p == nil { 13382 break 13383 } 13384 13385 // Write the point to the point encoder. 13386 if err := penc.EncodeIntegerPoint(p); err != nil { 13387 return err 13388 } 13389 } 13390 13391 // Emit final stats. 13392 if err := enc.encodeStats(itr.Stats()); err != nil { 13393 return err 13394 } 13395 return nil 13396 } 13397 13398 // encodeUnsignedIterator encodes all points from itr to the underlying writer. 13399 func (enc *IteratorEncoder) encodeUnsignedIterator(itr UnsignedIterator) error { 13400 ticker := time.NewTicker(enc.StatsInterval) 13401 defer ticker.Stop() 13402 13403 // Emit initial stats. 13404 if err := enc.encodeStats(itr.Stats()); err != nil { 13405 return err 13406 } 13407 13408 // Continually stream points from the iterator into the encoder. 13409 penc := NewUnsignedPointEncoder(enc.w) 13410 for { 13411 // Emit stats periodically. 13412 select { 13413 case <-ticker.C: 13414 if err := enc.encodeStats(itr.Stats()); err != nil { 13415 return err 13416 } 13417 default: 13418 } 13419 13420 // Retrieve the next point from the iterator. 13421 p, err := itr.Next() 13422 if err != nil { 13423 return err 13424 } else if p == nil { 13425 break 13426 } 13427 13428 // Write the point to the point encoder. 13429 if err := penc.EncodeUnsignedPoint(p); err != nil { 13430 return err 13431 } 13432 } 13433 13434 // Emit final stats. 13435 if err := enc.encodeStats(itr.Stats()); err != nil { 13436 return err 13437 } 13438 return nil 13439 } 13440 13441 // encodeStringIterator encodes all points from itr to the underlying writer. 13442 func (enc *IteratorEncoder) encodeStringIterator(itr StringIterator) error { 13443 ticker := time.NewTicker(enc.StatsInterval) 13444 defer ticker.Stop() 13445 13446 // Emit initial stats. 13447 if err := enc.encodeStats(itr.Stats()); err != nil { 13448 return err 13449 } 13450 13451 // Continually stream points from the iterator into the encoder. 13452 penc := NewStringPointEncoder(enc.w) 13453 for { 13454 // Emit stats periodically. 13455 select { 13456 case <-ticker.C: 13457 if err := enc.encodeStats(itr.Stats()); err != nil { 13458 return err 13459 } 13460 default: 13461 } 13462 13463 // Retrieve the next point from the iterator. 13464 p, err := itr.Next() 13465 if err != nil { 13466 return err 13467 } else if p == nil { 13468 break 13469 } 13470 13471 // Write the point to the point encoder. 13472 if err := penc.EncodeStringPoint(p); err != nil { 13473 return err 13474 } 13475 } 13476 13477 // Emit final stats. 13478 if err := enc.encodeStats(itr.Stats()); err != nil { 13479 return err 13480 } 13481 return nil 13482 } 13483 13484 // encodeBooleanIterator encodes all points from itr to the underlying writer. 13485 func (enc *IteratorEncoder) encodeBooleanIterator(itr BooleanIterator) error { 13486 ticker := time.NewTicker(enc.StatsInterval) 13487 defer ticker.Stop() 13488 13489 // Emit initial stats. 13490 if err := enc.encodeStats(itr.Stats()); err != nil { 13491 return err 13492 } 13493 13494 // Continually stream points from the iterator into the encoder. 13495 penc := NewBooleanPointEncoder(enc.w) 13496 for { 13497 // Emit stats periodically. 13498 select { 13499 case <-ticker.C: 13500 if err := enc.encodeStats(itr.Stats()); err != nil { 13501 return err 13502 } 13503 default: 13504 } 13505 13506 // Retrieve the next point from the iterator. 13507 p, err := itr.Next() 13508 if err != nil { 13509 return err 13510 } else if p == nil { 13511 break 13512 } 13513 13514 // Write the point to the point encoder. 13515 if err := penc.EncodeBooleanPoint(p); err != nil { 13516 return err 13517 } 13518 } 13519 13520 // Emit final stats. 13521 if err := enc.encodeStats(itr.Stats()); err != nil { 13522 return err 13523 } 13524 return nil 13525 }