github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/test_framework/search/similarity.go (about) 1 package search 2 3 import ( 4 "fmt" 5 . "github.com/balzaczyy/golucene/core/search" 6 "github.com/balzaczyy/golucene/core/util" 7 "math" 8 "math/rand" 9 "sync" 10 ) 11 12 // search/RandomSimilarityProvider.java 13 14 var allSims = func() []Similarity { 15 var ans []Similarity 16 ans = append(ans, NewDefaultSimilarity()) 17 // ans = append(ans, newBM25Similarity()) 18 // for _, basicModel := range BASIC_MODELS { 19 // for _, afterEffect := range AFTER_EFFECTS { 20 // for _, normalization := range NORMALIZATIONS { 21 // ans = append(ans, newDFRSimilarity(basicModel, afterEffect, normalization)) 22 // } 23 // } 24 // } 25 // for _, distribution := range DISTRIBUTIONS { 26 // for _, lambda := range LAMBDAS { 27 // for _, normalization := range NORMALIZATIONS { 28 // ans = append(ans, newIBSimilarity(ditribution, lambda, normalization)) 29 // } 30 // } 31 // } 32 // ans = append(ans, newLMJelinekMercerSimilarity(0.1)) 33 // ans = append(ans, newLMJelinekMercerSimilarity(0.7)) 34 return ans 35 }() 36 37 /* 38 Similarity implementation that randomizes Similarity implementations 39 per-field. 40 41 The choices are 'sticky', so the selected algorithm is ways used for 42 the same field. 43 */ 44 type RandomSimilarityProvider struct { 45 *PerFieldSimilarityWrapper 46 sync.Locker 47 defaultSim *DefaultSimilarity 48 knownSims []Similarity 49 previousMappings map[string]Similarity 50 perFieldSeed int 51 coordType int // 0 = no coord, 1 = coord, 2 = crazy coord 52 shouldQueryNorm bool 53 } 54 55 func NewRandomSimilarityProvider(r *rand.Rand) *RandomSimilarityProvider { 56 sims := make([]Similarity, len(allSims)) 57 for i, v := range r.Perm(len(allSims)) { 58 sims[i] = allSims[v] 59 assert(sims[i] != nil) 60 } 61 ans := &RandomSimilarityProvider{ 62 Locker: &sync.Mutex{}, 63 defaultSim: NewDefaultSimilarity(), 64 previousMappings: make(map[string]Similarity), 65 perFieldSeed: r.Int(), 66 coordType: r.Intn(3), 67 shouldQueryNorm: r.Intn(2) == 0, 68 knownSims: sims, 69 } 70 ans.PerFieldSimilarityWrapper = NewPerFieldSimilarityWrapper(ans) 71 return ans 72 } 73 74 func (rp *RandomSimilarityProvider) Coord(overlap, maxOverlap int) float32 { 75 panic("niy") 76 } 77 78 func (rp *RandomSimilarityProvider) QueryNorm(sumOfSquaredWeights float32) float32 { 79 if rp.shouldQueryNorm { 80 return rp.defaultSim.QueryNorm(sumOfSquaredWeights) 81 } 82 return 1.0 83 } 84 85 func (p *RandomSimilarityProvider) Get(name string) Similarity { 86 p.Lock() 87 defer p.Unlock() 88 sim, ok := p.previousMappings[name] 89 if !ok { 90 hash := int(math.Abs(math.Pow(float64(p.perFieldSeed), float64(util.Hashstr(name))))) 91 sim = p.knownSims[hash%len(p.knownSims)] 92 p.previousMappings[name] = sim 93 } 94 assert(sim != nil) 95 return sim 96 } 97 98 func assert(ok bool) { 99 assert2(ok, "assert fail") 100 } 101 102 func assert2(ok bool, msg string, args ...interface{}) { 103 if !ok { 104 panic(fmt.Sprintf(msg, args...)) 105 } 106 } 107 108 func (rp *RandomSimilarityProvider) String() string { 109 rp.Lock() // synchronized 110 defer rp.Unlock() 111 var coordMethod string 112 switch rp.coordType { 113 case 0: 114 coordMethod = "no" 115 case 1: 116 coordMethod = "yes" 117 default: 118 coordMethod = "crazy" 119 } 120 return fmt.Sprintf("RandomSimilarityProvider(queryNorm=%v,coord=%v): %v", 121 rp.shouldQueryNorm, coordMethod, rp.previousMappings) 122 }