influxdb无法实现关联表_Influxdb中Select查询请求结果涉及到的一些数据结构

本文详细介绍了InfluxDB中查询数据结构,包括Series、Tags、Row和Iterator的定义与工作原理。重点讲解了浮点数Iterator的实现,如bufFloatIterator、floatMergeIterator和floatSortedMergeIterator的内部逻辑,以及如何处理数据窗口和排序。此外,还提到了其他相关迭代器,如floatLimitIterator和floatFillIterator,用于限制数据和填充缺失值。
摘要由CSDN通过智能技术生成

前言

关于Select查询请求结果涉及到的一些数据结构

Series定义type Series struct {

// Name is the measurement name.

Name string

// Tags for the series.

Tags Tags

id uint64

}

type Tags struct {

id string

m  map[string]string}Series其实就是measurement和tags的组合,tags是tag key和tag value的map.这个Tags的id是如何产生的呢,其实就是对tag key和tag value编码到[]byte: tagkey1\0tagkey2\0...\tagvalue1\0tagvalue2\0...,具体实现定义在query/point.go中的encodeTags

Row定义type Row struct {

Time int64    // Series contains the series metadata for this row.

Series Series    // Values contains the values within the current row.

Values []interface{}

}Row表示查询结果集中的每一行, 其中的Values表示是返回的Fields的集合

IteratorbufFloatIterator定义type bufFloatIterator struct {

itr FloatIterator

buf *FloatPoint

}

相当于c里面的链表元素,itr指向下一个元素的指针,buf表示当前元素,即FloatPoint类型的链表的迭代器.看一下FloatPoint定义type FloatPoint struct {

Name string

Tags Tags

Time  int64

Value float64

Aux   []interface{}    // Total number of points that were combined into this point from an aggregate.

// If this is zero, the point is not the result of an aggregate function.

Aggregated uint32

Nil        bool}

定义在query/point.gen.go中, 表示一条field为float类型的数据Next实现func (itr *bufFloatIterator) Next() (*FloatPoint, error) {

buf := itr.buf    if buf != nil {

itr.buf = nil

return buf, nil

}    return itr.itr.Next()

}

当前Iterator的值不为空,就返回当前的buf, 当前的值为空,就返回itr.itr.Next(),即指向的下一个元素unread: iterator回退操作func (itr *bufFloatIterator) unread(v *FloatPoint) { itr.buf = v }floatMergeIterator组合了多个floatIterator

我们来看下定义type floatMergeIterator struct {

inputs []FloatIterator

heap   *floatMergeHeap

init   bool

closed bool

mu     sync.RWMutex    // Current iterator and window.

curr   *floatMergeHeapItem

window struct {

name      string

tags      string

startTime int64

endTime   int64

}

}

因为要作merge, 这里需要对其管理的所有Interator元素作排序,这里用到了golang的container/heap作堆排, 大小根堆不太清楚了大家自行google吧。

因为要用golang的container/heap来管理,需要实现下面规定的接口,type Interface interface {

sort.Interface

Push(x interface{}) // add x as element Len()

Pop() interface{}   // remove and return element Len() - 1.}

floatMergeIterator定义中的floatMergeHeap即实现了上面的接口,我们主要来看一下比较函数的实现,比较的其实就是FloatPointfunc (h *floatMergeHeap) Less(i, j int) bool {

x, err := h.items[i].itr.peek()    if err != nil {        return true

}

y, err := h.items[j].itr.peek()    if err != nil {        return false

}    if h.opt.Ascending {        if x.Name != y.Name {            return x.Name 

} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {            return xTags.ID() 

}

} else {        if x.Name != y.Name {            return x.Name > y.Name

} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {            return xTags.ID() > yTags.ID()

}

}

xt, _ := h.opt.Window(x.Time)

yt, _ := h.opt.Window(y.Time)    if h.opt.Ascending {        return xt 

}    return xt > yt

}

比较的优先级先是FloatPoint的measurement名,然后是tagset id, 最后是time,将这个比较函数我们就可以知道.看一下结构:

float_merge_iterator.png

Next函数的实现func (itr *floatMergeIterator) Next() (*FloatPoint, error) {

itr.mu.RLock()

defer itr.mu.RUnlock()    if itr.closed {        return nil, nil

}

// 堆排的heap数据结构并不会一开始就构造,而是在首次遍历时初始化构造

if !itr.init {

items := itr.heap.items

itr.heap.items = make([]*floatMergeHeapItem, 0, len(items))        for _, item := range items {            if p, err := item.itr.peek(); err != nil {                return nil, err

} else if p == nil {                continue

}

itr.heap.items = append(itr.heap.items, item)

}

heap.Init(itr.heap)

itr.init = true

}    for {        // Retrieve the next iterator if we don't have one.

if itr.curr == nil {            if len(itr.heap.items) == 0 {                r

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值