github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/cmd/importer/rand.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package main 15 16 import ( 17 "fmt" 18 "math/rand" 19 "time" 20 21 "github.com/whtcorpsinc/log" 22 "go.uber.org/zap" 23 ) 24 25 const ( 26 alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 27 yearFormat = "2006" 28 dateFormat = "2006-01-02" 29 timeFormat = "15:04:05" 30 dateTimeFormat = "2006-01-02 15:04:05" 31 32 // Used by randString 33 letterIdxBits = 6 // 6 bits to represent a letter index 34 letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits 35 letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits 36 ) 37 38 func init() { 39 rand.Seed(time.Now().UnixNano()) 40 } 41 42 func randInt(min int, max int) int { 43 return min + rand.Intn(max-min+1) 44 } 45 46 func randInt64(min int64, max int64) int64 { 47 return min + rand.Int63n(max-min+1) 48 } 49 50 // reference: http://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang 51 func randString(n int) string { 52 b := make([]byte, n) 53 // A src.Int63() generates 63 random bits, enough for letterIdxMax characters! 54 for i, cache, remain := n-1, rand.Int63(), letterIdxMax; i >= 0; { 55 if remain == 0 { 56 cache, remain = rand.Int63(), letterIdxMax 57 } 58 if idx := int(cache & letterIdxMask); idx < len(alphabet) { 59 b[i] = alphabet[idx] 60 i-- 61 } 62 cache >>= letterIdxBits 63 remain-- 64 } 65 66 return string(b) 67 } 68 69 func randDate(col *column) string { 70 if col.hist != nil { 71 return col.hist.randDate("DAY", "%Y-%m-%d", dateFormat) 72 } 73 74 min, max := col.min, col.max 75 if len(min) == 0 { 76 year := time.Now().Year() 77 month := randInt(1, 12) 78 day := randInt(1, 28) 79 return fmt.Sprintf("%04d-%02d-%02d", year, month, day) 80 } 81 82 minTime, err := time.Parse(dateFormat, min) 83 if err != nil { 84 log.Warn("parse min date failed", zap.Error(err)) 85 } 86 if len(max) == 0 { 87 t := minTime.Add(time.Duration(randInt(0, 365)) * 24 * time.Hour) 88 return fmt.Sprintf("%04d-%02d-%02d", t.Year(), t.Month(), t.Day()) 89 } 90 91 maxTime, err := time.Parse(dateFormat, max) 92 if err != nil { 93 log.Warn("parse max date failed", zap.Error(err)) 94 } 95 days := int(maxTime.Sub(minTime).Hours() / 24) 96 t := minTime.Add(time.Duration(randInt(0, days)) * 24 * time.Hour) 97 return fmt.Sprintf("%04d-%02d-%02d", t.Year(), t.Month(), t.Day()) 98 } 99 100 func randTime(col *column) string { 101 if col.hist != nil { 102 return col.hist.randDate("SECOND", "%H:%i:%s", timeFormat) 103 } 104 min, max := col.min, col.max 105 if len(min) == 0 || len(max) == 0 { 106 hour := randInt(0, 23) 107 min := randInt(0, 59) 108 sec := randInt(0, 59) 109 return fmt.Sprintf("%02d:%02d:%02d", hour, min, sec) 110 } 111 112 minTime, err := time.Parse(timeFormat, min) 113 if err != nil { 114 log.Warn("parse min time failed", zap.Error(err)) 115 } 116 maxTime, err := time.Parse(timeFormat, max) 117 if err != nil { 118 log.Warn("parse max time failed", zap.Error(err)) 119 } 120 seconds := int(maxTime.Sub(minTime).Seconds()) 121 t := minTime.Add(time.Duration(randInt(0, seconds)) * time.Second) 122 return fmt.Sprintf("%02d:%02d:%02d", t.Hour(), t.Minute(), t.Second()) 123 } 124 125 func randTimestamp(col *column) string { 126 if col.hist != nil { 127 return col.hist.randDate("SECOND", "%Y-%m-%d %H:%i:%s", dateTimeFormat) 128 } 129 min, max := col.min, col.max 130 if len(min) == 0 { 131 year := time.Now().Year() 132 month := randInt(1, 12) 133 day := randInt(1, 28) 134 hour := randInt(0, 23) 135 min := randInt(0, 59) 136 sec := randInt(0, 59) 137 return fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, sec) 138 } 139 140 minTime, err := time.Parse(dateTimeFormat, min) 141 if err != nil { 142 log.Warn("parse min timestamp failed", zap.Error(err)) 143 } 144 if len(max) == 0 { 145 t := minTime.Add(time.Duration(randInt(0, 365)) * 24 * time.Hour) 146 return fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second()) 147 } 148 149 maxTime, err := time.Parse(dateTimeFormat, max) 150 if err != nil { 151 log.Warn("parse max timestamp failed", zap.Error(err)) 152 } 153 seconds := int(maxTime.Sub(minTime).Seconds()) 154 t := minTime.Add(time.Duration(randInt(0, seconds)) * time.Second) 155 return fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second()) 156 } 157 158 func randYear(col *column) string { 159 if col.hist != nil { 160 return col.hist.randDate("YEAR", "%Y", yearFormat) 161 } 162 min, max := col.min, col.max 163 if len(min) == 0 || len(max) == 0 { 164 return fmt.Sprintf("%04d", time.Now().Year()-randInt(0, 10)) 165 } 166 167 minTime, err := time.Parse(yearFormat, min) 168 if err != nil { 169 log.Warn("parse min year failed", zap.Error(err)) 170 } 171 maxTime, err := time.Parse(yearFormat, max) 172 if err != nil { 173 log.Warn("parse max year failed", zap.Error(err)) 174 } 175 seconds := int(maxTime.Sub(minTime).Seconds()) 176 t := minTime.Add(time.Duration(randInt(0, seconds)) * time.Second) 177 return fmt.Sprintf("%04d", t.Year()) 178 }