util.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. package model
  2. import (
  3. "errors"
  4. "math/rand"
  5. "rocommon/service"
  6. "rocommon/util"
  7. "roserver/serverproto"
  8. "strconv"
  9. "strings"
  10. "time"
  11. )
  12. var lastTimeStamp uint64 = 0
  13. var sequence = 0
  14. const (
  15. STAMP_SHIFT_BITS = 22 //时间戳左移位数
  16. ZONE_MASK = 32768 //2^15 15位->32767
  17. ZONE_MASK_MULTI = 0x7fff //15位
  18. SEQUENCE_MASK = 0xfff //12位
  19. SEQUENCE_BITS = 12 //序列号位数
  20. SEQUENCE_MASK_MULTI = 0xffff
  21. //SEQUENCE_BITS_MULTI = 16 //序列号12位
  22. SEQUENCE_BITS_MULTI = 20 //序列号12位
  23. TIMESTAMP_BITS_MULTI = 32 //时间戳占用位数
  24. LOGIC_BITS = 5 //logic ID 5占位
  25. LOGIC_MASK = 0x1f
  26. LOGIC_MASK64 = 0x0000000000007fff
  27. ZONE_MASK64_MULTI = 0x000000000000FFC0
  28. )
  29. // role uuid
  30. func GenerateUid() uint64 {
  31. serviceConfig := service.GetServiceConfig()
  32. zone := serviceConfig.Node.Zone
  33. id := serviceConfig.Node.Id
  34. return GUIDCreate(zone, id)
  35. }
  36. func GenerateUidByZone(zone int) uint64 {
  37. serviceConfig := service.GetServiceConfig()
  38. if zone <= 0 {
  39. zone = serviceConfig.Node.Zone
  40. }
  41. id := serviceConfig.Node.Id
  42. return GUIDCreate(zone, id)
  43. }
  44. func ParseUid(uid uint64) (zone, id int32) {
  45. id = int32(uid & LOGIC_MASK)
  46. zone = int32((uid >> LOGIC_BITS) & LOGIC_MASK64)
  47. return
  48. }
  49. func GUIDCreate(zone, id int) uint64 {
  50. currentTimeStamp := uint64(time.Now().Unix())
  51. if lastTimeStamp == 0 {
  52. lastTimeStamp = currentTimeStamp
  53. }
  54. //zone[2^12] id[2^8]
  55. if zone >= ZONE_MASK || id >= 256 {
  56. util.ErrorF("GUIDCreate zone=%v[%v] id=%v[%v] invalid", zone, ZONE_MASK, id, 256)
  57. return 0
  58. }
  59. if lastTimeStamp == currentTimeStamp {
  60. sequence++
  61. if sequence > SEQUENCE_MASK {
  62. //一秒内尝试的数量超过上限
  63. return 0
  64. }
  65. } else {
  66. lastTimeStamp = currentTimeStamp
  67. sequence = 1
  68. }
  69. //zone -> 2^15
  70. //logicid -> 2^5
  71. var uid uint64 = 0
  72. //前32位时间戳(秒)
  73. uid |= lastTimeStamp << TIMESTAMP_BITS_MULTI
  74. //12位序列号
  75. uid |= uint64(sequence&SEQUENCE_MASK_MULTI) << SEQUENCE_BITS_MULTI
  76. //15位区域id
  77. uid |= uint64(zone&ZONE_MASK_MULTI) << LOGIC_BITS
  78. //左后是逻辑ID(服务器id)
  79. uid |= uint64(id & LOGIC_MASK)
  80. return uid
  81. }
  82. func GUIDCreateTest(zone, id int) uint64 {
  83. currentTimeStamp := uint64(time.Now().Unix())
  84. if lastTimeStamp == 0 {
  85. lastTimeStamp = currentTimeStamp
  86. }
  87. if zone > ZONE_MASK {
  88. return 0
  89. }
  90. if lastTimeStamp == currentTimeStamp {
  91. sequence++
  92. if sequence > 256 {
  93. //一秒内尝试的数量超过上限
  94. return 0
  95. }
  96. } else {
  97. lastTimeStamp = currentTimeStamp
  98. sequence = 1
  99. }
  100. var uid uint64 = 0
  101. //前32位时间戳(秒)
  102. uid |= (lastTimeStamp >> 1) << 23
  103. //16位序列号
  104. uid |= uint64(sequence&SEQUENCE_MASK_MULTI) << 15
  105. //8位区域id
  106. uid |= uint64(zone&ZONE_MASK_MULTI) << 5
  107. //左后是逻辑ID(服务器id)
  108. uid |= uint64(id & LOGIC_MASK)
  109. return uid
  110. }
  111. // item id
  112. var uuidLow uint32 = 0
  113. var uuidHigh uint32 = 1
  114. func UUIDCreate() uint64 {
  115. if uuidLow == 0 {
  116. uuidLow = uint32(time.Now().Unix())
  117. }
  118. uuidHigh++
  119. uuid := uint64(uuidHigh)
  120. uuid <<= 32
  121. uuid += uint64(uuidLow)
  122. return uuid
  123. }
  124. // 是否同一天(24点)
  125. func IsSameDay(source int64) bool {
  126. loc := util.GetLoc()
  127. nowTime := time.Unix(util.GetTimeSeconds(), 0).In(loc)
  128. sourceTime := time.Unix(source, 0).In(loc)
  129. if nowTime.YearDay() != sourceTime.YearDay() {
  130. return true
  131. }
  132. return false
  133. }
  134. // 是否是同一天(24点)
  135. func IsSameDayMs(sourceMs uint64) int {
  136. loc := util.GetLoc()
  137. timeS := int64(sourceMs / 1000)
  138. timeMS := int64(sourceMs % 1000)
  139. tempTime := time.Unix(timeS, timeMS).In(loc)
  140. nowTime := time.Unix(util.GetTimeSeconds(), 0).In(loc)
  141. nt1 := nowTime.YearDay()
  142. nt2 := tempTime.YearDay()
  143. if nt1 != nt2 {
  144. return nt1 - nt2
  145. }
  146. return 0
  147. }
  148. // 判断是否是同一天true不天, false同一天(凌晨晨5点)
  149. func IsDailyResetHour5(sourceMs uint64) bool {
  150. if sourceMs <= 0 {
  151. return false
  152. }
  153. tempTime := util.GetTimeByUint64(sourceMs)
  154. nowTime := util.GetCurrentTimeNow()
  155. nt1 := nowTime.YearDay()
  156. nt2 := tempTime.YearDay()
  157. deltaDay := nt1 - nt2
  158. if nowTime.Year() != tempTime.Year() {
  159. if isLeapYear(tempTime.Year()) {
  160. deltaDay = 366 - nt2
  161. } else {
  162. deltaDay = 365 - nt2
  163. }
  164. deltaDay += nt1
  165. }
  166. if deltaDay < 0 {
  167. return false
  168. } else if deltaDay == 0 {
  169. if tempTime.Hour() < 5 && nowTime.Hour() >= 5 {
  170. return true
  171. }
  172. } else if deltaDay == 1 {
  173. if tempTime.Hour() < 5 || tempTime.Hour() >= 5 && nowTime.Hour() >= 5 {
  174. return true
  175. }
  176. } else {
  177. return true
  178. }
  179. return false
  180. }
  181. func isLeapYear(year int) bool {
  182. if year%4 == 0 && year%100 != 0 || year%400 == 0 {
  183. return true
  184. }
  185. return false
  186. }
  187. func Str2Num(str string) (int, error) {
  188. if str == "" {
  189. return 0, nil
  190. }
  191. str = strings.Replace(str, "\u00A0", "", -1)
  192. str = strings.Replace(str, "\u0020", "", -1)
  193. str = strings.Replace(str, "\u0009", "", -1)
  194. num, e := strconv.ParseInt(str, 10, 32)
  195. if e != nil {
  196. return 0, errors.New("service invalid num convert error:" + str)
  197. } else {
  198. return int(num), nil
  199. }
  200. }
  201. func Str2NumU64(str string) (uint64, error) {
  202. str = strings.Replace(str, "\u00A0", "", -1)
  203. str = strings.Replace(str, "\u0020", "", -1)
  204. num, e := strconv.ParseUint(str, 10, 64)
  205. if e != nil {
  206. return 0, errors.New("service invalid num convert error:" + str)
  207. } else {
  208. return num, nil
  209. }
  210. }
  211. func Str2Float32(str string) (float32, error) {
  212. str = strings.Replace(str, "\u00A0", "", -1)
  213. str = strings.Replace(str, "\u0020", "", -1)
  214. num, e := strconv.ParseFloat(str, 32)
  215. if e != nil {
  216. return 0, errors.New("service invalid num convert error:" + str)
  217. } else {
  218. return float32(num), nil
  219. }
  220. }
  221. func Str2Float32_2(str string) (float32, float32) {
  222. resList := strings.Split(str, ":")
  223. if len(resList) > 1 {
  224. resType, _ := Str2Float32(resList[0])
  225. resValue, _ := Str2Float32(resList[1])
  226. return resType, resValue
  227. }
  228. return 0, 0
  229. }
  230. func Str2Res(str string) (int32, int32) {
  231. resList := strings.Split(str, ":")
  232. if len(resList) > 1 {
  233. resType, _ := Str2Num(resList[0])
  234. resValue, _ := Str2Num(resList[1])
  235. return int32(resType), int32(resValue)
  236. }
  237. return 0, 0
  238. }
  239. func Str2ResFloat(str string) (int32, float32) {
  240. resList := strings.Split(str, ":")
  241. if len(resList) > 1 {
  242. resType, _ := Str2Num(resList[0])
  243. resValue, _ := Str2Float32(resList[1])
  244. return int32(resType), resValue
  245. }
  246. return 0, 0
  247. }
  248. func Str2ResBySep(str string, sep string) (int32, int32) {
  249. resList := strings.Split(str, sep)
  250. if len(resList) > 1 {
  251. resType, _ := Str2Num(resList[0])
  252. resValue, _ := Str2Num(resList[1])
  253. return int32(resType), int32(resValue)
  254. }
  255. return 0, 0
  256. }
  257. func Str2Res_3(str string) (int32, int32, int32) {
  258. resList := strings.Split(str, ":")
  259. if len(resList) >= 3 {
  260. value1, _ := Str2Num(resList[0])
  261. value2, _ := Str2Num(resList[1])
  262. value3, _ := Str2Num(resList[2])
  263. return int32(value1), int32(value2), int32(value3)
  264. }
  265. return 0, 0, 0
  266. }
  267. func Str2Res_4(str string) (int32, int32, int32, int32) {
  268. resList := strings.Split(str, ":")
  269. if len(resList) >= 4 {
  270. value1, _ := Str2Num(resList[0])
  271. value2, _ := Str2Num(resList[1])
  272. value3, _ := Str2Num(resList[2])
  273. value4, _ := Str2Num(resList[3])
  274. return int32(value1), int32(value2), int32(value3), int32(value4)
  275. }
  276. return 0, 0, 0, 0
  277. }
  278. func Str2Res_5(str string) (int32, int32, int32, int32, int32) {
  279. resList := strings.Split(str, ":")
  280. if len(resList) >= 5 {
  281. value1, _ := Str2Num(resList[0])
  282. value2, _ := Str2Num(resList[1])
  283. value3, _ := Str2Num(resList[2])
  284. value4, _ := Str2Num(resList[3])
  285. value5, _ := Str2Num(resList[4])
  286. return int32(value1), int32(value2), int32(value3), int32(value4), int32(value5)
  287. }
  288. return 0, 0, 0, 0, 0
  289. }
  290. // 最小堆
  291. type MinHeap struct {
  292. ItemList []int32
  293. }
  294. func (h *MinHeap) Len() int {
  295. return len(h.ItemList)
  296. }
  297. func (h *MinHeap) Less(i, j int) bool {
  298. return h.ItemList[i] < h.ItemList[j]
  299. }
  300. func (h *MinHeap) Swap(i, j int) {
  301. h.ItemList[i], h.ItemList[j] = h.ItemList[j], h.ItemList[i]
  302. }
  303. func (h *MinHeap) Push(item interface{}) {
  304. h.ItemList = append(h.ItemList, item.(int32))
  305. }
  306. func (h *MinHeap) Pop() (ret interface{}) {
  307. l := len(h.ItemList)
  308. h.ItemList, ret = h.ItemList[:l-1], h.ItemList[l-1]
  309. return
  310. }
  311. // 随机打乱数组Fisher-Yates随机置乱算法
  312. func GenRandomArray(selfArray []int32) []int32 {
  313. if len(selfArray) <= 0 {
  314. return nil
  315. }
  316. rand.Seed(time.Now().UnixNano())
  317. for i := len(selfArray) - 1; i > 0; i-- {
  318. randNum := rand.Intn(i + 1)
  319. selfArray[i], selfArray[randNum] = selfArray[randNum], selfArray[i]
  320. }
  321. return selfArray
  322. }
  323. func GenRandomArrayByLen(numLen int) []int32 {
  324. if numLen <= 0 {
  325. return nil
  326. }
  327. rand.Seed(time.Now().UnixNano())
  328. var selfArray []int32
  329. for idx := 0; idx < numLen; idx++ {
  330. selfArray = append(selfArray, int32(idx+1))
  331. }
  332. for i := len(selfArray) - 1; i > 0; i-- {
  333. randNum := rand.Intn(i + 1)
  334. selfArray[i], selfArray[randNum] = selfArray[randNum], selfArray[i]
  335. }
  336. return selfArray
  337. }
  338. // 字符串相似度算法
  339. func MessageLD(s, t string, ignoreCase bool) int {
  340. if ignoreCase {
  341. s = strings.ToLower(s)
  342. t = strings.ToLower(t)
  343. }
  344. d := make([][]int, len(s)+1)
  345. for i := range d {
  346. d[i] = make([]int, len(t)+1)
  347. }
  348. for i := range d {
  349. d[i][0] = i
  350. }
  351. for j := range d[0] {
  352. d[0][j] = j
  353. }
  354. for j := 1; j <= len(t); j++ {
  355. for i := 1; i <= len(s); i++ {
  356. if s[i-1] == t[j-1] {
  357. d[i][j] = d[i-1][j-1]
  358. } else {
  359. min := d[i-1][j]
  360. if d[i][j-1] < min {
  361. min = d[i][j-1]
  362. }
  363. if d[i-1][j-1] < min {
  364. min = d[i-1][j-1]
  365. }
  366. d[i][j] = min + 1
  367. }
  368. }
  369. }
  370. return d[len(s)][len(t)]
  371. }
  372. // 二倍均值算法,count剩余个数,amount剩余金额
  373. func DoubleAverage(count, amount int64) int64 {
  374. //最小钱
  375. min := int64(1)
  376. if count <= 0 {
  377. count = 1
  378. }
  379. if count == 1 {
  380. //返回剩余金额
  381. return amount
  382. }
  383. //计算最大可用金额,min最小是1分钱,减去的min,下面会加上,避免出现0分钱
  384. max := amount - min*count
  385. if max < 0 {
  386. return 0
  387. }
  388. //计算最大可用平均值
  389. avg := max / count
  390. //二倍均值基础加上最小金额,防止0出现,作为上限
  391. avg2 := 2*avg + min
  392. //随机红包金额序列元素,把二倍均值作为随机的最大数
  393. //rand.Seed(time.Now().UnixNano())
  394. //加min是为了避免出现0值,上面也减去了min
  395. x := rand.Int63n(avg2) + min
  396. return x
  397. }
  398. /*
  399. 使用说明
  400. rand.Seed(time.Now().UnixNano())
  401. var sumAmount int64 = 0
  402. var remainAmount int64 = 2
  403. rewardNum := 10
  404. for idx := 0; idx < rewardNum; idx++ {
  405. delAmount := DoubleAverage(int64(rewardNum-idx), int64(remainAmount))
  406. remainAmount -= delAmount
  407. sumAmount += delAmount
  408. log.Printf("delAmount=%v", delAmount)
  409. }
  410. log.Printf("sumAmount=%v", sumAmount)
  411. */
  412. func Str2ResMapList(strList []string, resList map[int32]int32) {
  413. for _, str := range strList {
  414. k, v := Str2Res(str)
  415. if k <= 0 || v <= 0 {
  416. continue
  417. }
  418. resList[k] += v
  419. }
  420. }
  421. func Str2ResSliceList(strList []string) []*serverproto.KeyValueType {
  422. var outList []*serverproto.KeyValueType
  423. for _, str := range strList {
  424. k, v := Str2Res(str)
  425. if k <= 0 || v <= 0 {
  426. continue
  427. }
  428. outList = append(outList, &serverproto.KeyValueType{
  429. Key: k,
  430. Value: v,
  431. })
  432. }
  433. return outList
  434. }