github.com/XiaoMi/Gaea@v1.2.5/proxy/router/numkey.go (about)

     1  // Copyright 2016 The kingshard Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"): you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // 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, WITHOUT
    11  // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    12  // License for the specific language governing permissions and limitations
    13  // under the License.
    14  
    15  package router
    16  
    17  import (
    18  	"fmt"
    19  	"math"
    20  	"strconv"
    21  	"strings"
    22  	"time"
    23  
    24  	"github.com/XiaoMi/Gaea/core/errors"
    25  )
    26  
    27  const (
    28  	// MinNumKey min int64
    29  	MinNumKey = math.MinInt64
    30  	// MaxNumKey max int64
    31  	MaxNumKey = math.MaxInt64
    32  )
    33  
    34  // NumKeyRange [start,end)
    35  type NumKeyRange struct {
    36  	Start int64
    37  	End   int64
    38  }
    39  
    40  // MapKey key range
    41  func (kr NumKeyRange) MapKey() string {
    42  	return fmt.Sprintf("%d-%d", kr.Start, kr.End)
    43  }
    44  
    45  // Contains check if range contains i
    46  func (kr NumKeyRange) Contains(i int64) bool {
    47  	return kr.Start <= i && (kr.End == MaxNumKey || i < kr.End)
    48  }
    49  
    50  func (kr NumKeyRange) String() string {
    51  	return fmt.Sprintf("{Start: %d, End: %d}", kr.Start, kr.End)
    52  }
    53  
    54  // ParseNumSharding parse num shard
    55  func ParseNumSharding(Locations []int, TableRowLimit int) ([]NumKeyRange, error) {
    56  	tableCount := 0
    57  	length := len(Locations)
    58  
    59  	for i := 0; i < length; i++ {
    60  		tableCount += Locations[i]
    61  	}
    62  
    63  	ranges := make([]NumKeyRange, tableCount)
    64  	for i := 0; i < tableCount; i++ {
    65  		ranges[i].Start = int64(i * TableRowLimit)
    66  		ranges[i].End = int64((i + 1) * TableRowLimit)
    67  	}
    68  	return ranges, nil
    69  }
    70  
    71  // ParseDayRange return date of daynumber by order
    72  //20151201-20151205
    73  //20151201,20151202,20151203,20151204,20151205
    74  func ParseDayRange(dateRange string) ([]int, error) {
    75  	timeFormat := "20060102"
    76  	dateDays := make([]int, 0)
    77  	dateLength := 8
    78  
    79  	dateTmp := strings.SplitN(dateRange, "-", 2)
    80  	if len(dateTmp) == 1 {
    81  		if len(dateTmp[0]) != dateLength {
    82  			return nil, errors.ErrDateRangeIllegal
    83  		}
    84  		dateNum, err := strconv.Atoi(dateTmp[0])
    85  		if err != nil {
    86  			return nil, err
    87  		}
    88  		return []int{dateNum}, nil
    89  	}
    90  	if len(dateTmp) != 2 {
    91  		return nil, errors.ErrDateRangeIllegal
    92  	}
    93  	if len(dateTmp[0]) != dateLength || len(dateTmp[1]) != dateLength {
    94  		return nil, errors.ErrDateRangeIllegal
    95  	}
    96  	//change the begin day and the end day
    97  	if dateTmp[1] < dateTmp[0] {
    98  		dateTmp[0], dateTmp[1] = dateTmp[1], dateTmp[0]
    99  	}
   100  
   101  	begin, err := time.Parse(timeFormat, dateTmp[0])
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  	end, err := time.Parse(timeFormat, dateTmp[1])
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  
   110  	duration := end.Sub(begin)
   111  	daysCount := int(duration.Hours() / 24)
   112  
   113  	for i := 0; i <= daysCount; i++ {
   114  		date := begin.Add(time.Hour * time.Duration(24*i))
   115  		dateStr := date.Format("20060102")
   116  		dateNum, err := strconv.Atoi(dateStr)
   117  		if err != nil {
   118  			return nil, err
   119  		}
   120  		dateDays = append(dateDays, dateNum)
   121  	}
   122  	return dateDays, nil
   123  }
   124  
   125  // ParseMonthRange return date of month by order
   126  //201510-201512
   127  //201510,201511,201512
   128  func ParseMonthRange(dateRange string) ([]int, error) {
   129  	dateMonth := make([]int, 0)
   130  	dateLength := 6
   131  
   132  	dateTmp := strings.SplitN(dateRange, "-", 2)
   133  	if len(dateTmp) == 1 {
   134  		if len(dateTmp[0]) != dateLength {
   135  			return nil, errors.ErrDateRangeIllegal
   136  		}
   137  		dateNum, err := strconv.Atoi(dateTmp[0])
   138  		if err != nil {
   139  			return nil, err
   140  		}
   141  		return []int{dateNum}, nil
   142  	}
   143  	if len(dateTmp) != 2 {
   144  		return nil, errors.ErrDateRangeIllegal
   145  	}
   146  	if len(dateTmp[0]) != dateLength || len(dateTmp[1]) != dateLength {
   147  		return nil, errors.ErrDateRangeIllegal
   148  	}
   149  	//change the begin month and the end month
   150  	if dateTmp[1] < dateTmp[0] {
   151  		dateTmp[0], dateTmp[1] = dateTmp[1], dateTmp[0]
   152  	}
   153  
   154  	beginYear, err := strconv.Atoi(dateTmp[0][:4])
   155  	if err != nil {
   156  		return nil, err
   157  	}
   158  	beginMonth, err := strconv.Atoi(dateTmp[0][4:])
   159  	if err != nil {
   160  		return nil, err
   161  	}
   162  
   163  	endYear, err := strconv.Atoi(dateTmp[1][:4])
   164  	if err != nil {
   165  		return nil, err
   166  	}
   167  	endMonth, err := strconv.Atoi(dateTmp[1][4:])
   168  	if err != nil {
   169  		return nil, err
   170  	}
   171  	// how many months between the two date
   172  	monthCount := (endYear-beginYear)*12 + endMonth - beginMonth + 1
   173  	monthTmp := beginMonth
   174  	for i := 0; i < monthCount; i++ {
   175  		if 12 < monthTmp {
   176  			monthTmp = monthTmp % 12
   177  			beginYear++
   178  		}
   179  
   180  		monthNum := beginYear*100 + monthTmp
   181  		dateMonth = append(dateMonth, monthNum)
   182  		monthTmp++
   183  	}
   184  
   185  	return dateMonth, nil
   186  }
   187  
   188  // ParseYearRange return date of year by order
   189  //2013-2015
   190  //2013,2014,2015
   191  func ParseYearRange(dateRange string) ([]int, error) {
   192  	dateYear := make([]int, 0)
   193  	dateLength := 4
   194  
   195  	dateTmp := strings.SplitN(dateRange, "-", 2)
   196  	if len(dateTmp) == 1 {
   197  		if len(dateTmp[0]) != dateLength {
   198  			return nil, errors.ErrDateRangeIllegal
   199  		}
   200  		dateNum, err := strconv.Atoi(dateTmp[0])
   201  		if err != nil {
   202  			return nil, err
   203  		}
   204  		return []int{dateNum}, nil
   205  	}
   206  	if len(dateTmp) != 2 {
   207  		return nil, errors.ErrDateRangeIllegal
   208  	}
   209  	//change the begin year and the end year
   210  	if dateTmp[1] < dateTmp[0] {
   211  		dateTmp[0], dateTmp[1] = dateTmp[1], dateTmp[0]
   212  	}
   213  	beginYear, err := strconv.Atoi(dateTmp[0])
   214  	if err != nil {
   215  		return nil, err
   216  	}
   217  	endYear, err := strconv.Atoi(dateTmp[1])
   218  	if err != nil {
   219  		return nil, err
   220  	}
   221  
   222  	for i := beginYear; i <= endYear; i++ {
   223  		dateYear = append(dateYear, i)
   224  	}
   225  
   226  	return dateYear, nil
   227  }