geom/primes/wheel.go

59 lines
1.1 KiB
Go
Raw Normal View History

2019-12-21 12:44:19 +00:00
package primes
type wheel struct {
cache Cache
elements []int64
primes []int64
size int64
offset int
n int64
}
func newWheel6(cache Cache) *wheel {
return &wheel{cache, []int64{2, 4}, []int64{2, 3}, 6, 0, 5}
}
func (s *wheel) resetTo(n int64) {
nn := n + 1
s.n = (nn/s.size)*s.size - 1
s.offset = 0
for s.n+s.elements[s.offset] <= n {
s.next()
}
}
func (s *wheel) next() int64 {
s.n += s.elements[s.offset]
s.offset = (s.offset + 1) % len(s.elements)
return s.n
}
func (s *wheel) expand() *wheel {
prime := s.primes[len(s.primes)-1]
it := NewIteratorFromCache(s.cache)
for it.Next() && it.Get() <= prime {
}
prime = it.Get()
if s.n <= prime {
return nil
}
primes := append([]int64(nil), s.primes...)
primes = append(primes, prime)
var elements []int64
var v int64 = -1
var inc int64
for i := int64(0); i < prime; i++ {
for _, el := range s.elements {
v += el
inc += el
if 0 != v%prime {
elements = append(elements, inc)
inc = 0
}
}
}
exp := &wheel{s.cache, elements, primes, s.size * prime, 0, s.n}
exp.resetTo(s.n)
return exp
}