github.com/coyove/common@v0.0.0-20240403014525-f70e643f9de8/goal/main.go (about) 1 package goal 2 3 import ( 4 "sync" 5 ) 6 7 type Goal struct { 8 goal uint64 9 overflowed map[uint64]uint64 10 overflow uint64 11 sync.Mutex 12 } 13 14 func New() *Goal { 15 return &Goal{ 16 overflowed: make(map[uint64]uint64), 17 } 18 } 19 20 const bit58_6 = 0xffffffffffffffc0 21 22 func (c *Goal) Meet(num uint64) bool { 23 c.Lock() 24 defer c.Unlock() 25 26 if num == c.goal { 27 c.goal = num + 1 28 return true 29 } 30 31 if num < c.goal { 32 return false 33 } 34 35 if num-c.goal > 1<<31 { 36 return false 37 } 38 39 c.overflow++ 40 score := uint64(0) 41 for i := c.goal; i < num; { 42 x, exist := c.overflowed[i&bit58_6] 43 if !exist { 44 break 45 } 46 47 AGAIN: 48 if x&(uint64(1)<<(i&0x3f)) > 0 { 49 score++ 50 if (i+1)&bit58_6 == i&bit58_6 && i < num { 51 i++ 52 goto AGAIN 53 } 54 i++ 55 } else { 56 break 57 } 58 } 59 60 if score == num-c.goal { 61 for i := c.goal; i < num; i++ { 62 tag := i & bit58_6 63 c.overflowed[tag] &= ^(uint64(1) << (i & 0x3f)) 64 if c.overflowed[tag] == 0 { 65 delete(c.overflowed, tag) 66 } 67 } 68 c.goal = num + 1 69 return true 70 } 71 72 c.overflowed[num&bit58_6] |= uint64(1) << (num & 0x3f) 73 return true 74 } 75 76 func (c *Goal) Goal() uint64 { 77 return c.goal 78 } 79 80 func (c *Goal) Overflow() int { 81 c.Lock() 82 defer c.Unlock() 83 return len(c.overflowed) 84 }