mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 13:32:25 -05:00 
			
		
		
		
	* Add SQLite support, fix un-thread-safe DB caches, small performance fixes Signed-off-by: kim (grufwub) <grufwub@gmail.com> * add SQLite licenses to README Signed-off-by: kim (grufwub) <grufwub@gmail.com> * appease the linter, and fix my dumbass-ery Signed-off-by: kim (grufwub) <grufwub@gmail.com> * make requested changes Signed-off-by: kim (grufwub) <grufwub@gmail.com> * add back comment Signed-off-by: kim (grufwub) <grufwub@gmail.com>
		
			
				
	
	
		
			70 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			70 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package bigfft
 | |
| 
 | |
| import (
 | |
| 	"math/big"
 | |
| )
 | |
| 
 | |
| // FromDecimalString converts the base 10 string
 | |
| // representation of a natural (non-negative) number
 | |
| // into a *big.Int.
 | |
| // Its asymptotic complexity is less than quadratic.
 | |
| func FromDecimalString(s string) *big.Int {
 | |
| 	var sc scanner
 | |
| 	z := new(big.Int)
 | |
| 	sc.scan(z, s)
 | |
| 	return z
 | |
| }
 | |
| 
 | |
| type scanner struct {
 | |
| 	// powers[i] is 10^(2^i * quadraticScanThreshold).
 | |
| 	powers []*big.Int
 | |
| }
 | |
| 
 | |
| func (s *scanner) chunkSize(size int) (int, *big.Int) {
 | |
| 	if size <= quadraticScanThreshold {
 | |
| 		panic("size < quadraticScanThreshold")
 | |
| 	}
 | |
| 	pow := uint(0)
 | |
| 	for n := size; n > quadraticScanThreshold; n /= 2 {
 | |
| 		pow++
 | |
| 	}
 | |
| 	// threshold * 2^(pow-1) <= size < threshold * 2^pow
 | |
| 	return quadraticScanThreshold << (pow - 1), s.power(pow - 1)
 | |
| }
 | |
| 
 | |
| func (s *scanner) power(k uint) *big.Int {
 | |
| 	for i := len(s.powers); i <= int(k); i++ {
 | |
| 		z := new(big.Int)
 | |
| 		if i == 0 {
 | |
| 			if quadraticScanThreshold%14 != 0 {
 | |
| 				panic("quadraticScanThreshold % 14 != 0")
 | |
| 			}
 | |
| 			z.Exp(big.NewInt(1e14), big.NewInt(quadraticScanThreshold/14), nil)
 | |
| 		} else {
 | |
| 			z.Mul(s.powers[i-1], s.powers[i-1])
 | |
| 		}
 | |
| 		s.powers = append(s.powers, z)
 | |
| 	}
 | |
| 	return s.powers[k]
 | |
| }
 | |
| 
 | |
| func (s *scanner) scan(z *big.Int, str string) {
 | |
| 	if len(str) <= quadraticScanThreshold {
 | |
| 		z.SetString(str, 10)
 | |
| 		return
 | |
| 	}
 | |
| 	sz, pow := s.chunkSize(len(str))
 | |
| 	// Scan the left half.
 | |
| 	s.scan(z, str[:len(str)-sz])
 | |
| 	// FIXME: reuse temporaries.
 | |
| 	left := Mul(z, pow)
 | |
| 	// Scan the right half
 | |
| 	s.scan(z, str[len(str)-sz:])
 | |
| 	z.Add(z, left)
 | |
| }
 | |
| 
 | |
| // quadraticScanThreshold is the number of digits
 | |
| // below which big.Int.SetString is more efficient
 | |
| // than subquadratic algorithms.
 | |
| // 1232 digits fit in 4096 bits.
 | |
| const quadraticScanThreshold = 1232
 |