mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-03 19:32:26 -06: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
 |