github.com/XiaoMi/Gaea@v1.2.5/proxy/plan/route_result.go (about)

     1  // Copyright 2019 The Gaea Authors. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package plan
    16  
    17  import (
    18  	"fmt"
    19  )
    20  
    21  // RouteResult is the route result of a statement
    22  // 遍历AST之后得到的路由结果
    23  // db, table唯一确定了一个路由, 这里只记录分片表的db和table, 如果是关联表, 必须关联到同一个父表
    24  type RouteResult struct {
    25  	db    string
    26  	table string
    27  
    28  	currentIndex int   // 当前遍历indexes位置下标
    29  	indexes      []int // 分片索引列表, 是有序的
    30  }
    31  
    32  // NewRouteResult constructor of RouteResult
    33  func NewRouteResult(db, table string, initIndexes []int) *RouteResult {
    34  	return &RouteResult{
    35  		db:      db,
    36  		table:   table,
    37  		indexes: initIndexes,
    38  	}
    39  }
    40  
    41  // Check check if the db and table is valid
    42  func (r *RouteResult) Check(db, table string) error {
    43  	if r.db != db {
    44  		return fmt.Errorf("db not equal, origin: %v, current: %v", r.db, db)
    45  	}
    46  	if r.table != table {
    47  		return fmt.Errorf("table not equal, origin: %v, current: %v", r.table, table)
    48  	}
    49  	return nil
    50  }
    51  
    52  // Inter inter indexes with origin indexes in RouteResult
    53  // 如果是关联表, db, table需要用父表的db和table
    54  func (r *RouteResult) Inter(indexes []int) {
    55  	r.indexes = interList(r.indexes, indexes)
    56  }
    57  
    58  // Union union indexes with origin indexes in RouteResult
    59  // 如果是关联表, db, table需要用父表的db和table
    60  func (r *RouteResult) Union(indexes []int) {
    61  	r.indexes = unionList(r.indexes, indexes)
    62  }
    63  
    64  // GetShardIndexes get shard indexes
    65  func (r *RouteResult) GetShardIndexes() []int {
    66  	return r.indexes
    67  }
    68  
    69  // GetCurrentTableIndex get current table index
    70  func (r *RouteResult) GetCurrentTableIndex() (int, error) {
    71  	if r.currentIndex >= len(r.indexes) {
    72  		return -1, fmt.Errorf("table index out of range")
    73  	}
    74  	return r.indexes[r.currentIndex], nil
    75  }
    76  
    77  // Next get next table index
    78  func (r *RouteResult) Next() int {
    79  	idx := r.currentIndex
    80  	r.currentIndex++
    81  	return r.indexes[idx]
    82  }
    83  
    84  // HasNext check if has next index
    85  func (r *RouteResult) HasNext() bool {
    86  	return r.currentIndex < len(r.indexes)
    87  }
    88  
    89  // Reset reset the cursor of index
    90  func (r *RouteResult) Reset() {
    91  	r.currentIndex = 0
    92  }