// Insert, Len, IsEmpty, Hash, Clear, AppendTo. func TestMoreBasics(t *testing.T) { set := new(intsets.Sparse) set.Insert(456) set.Insert(123) set.Insert(789) if set.Len() != 3 { t.Errorf("%s.Len: got %d, want 3", set, set.Len()) } if set.IsEmpty() { t.Errorf("%s.IsEmpty: got true", set) } if !set.Has(123) { t.Errorf("%s.Has(123): got false", set) } if set.Has(1234) { t.Errorf("%s.Has(1234): got true", set) } got := set.AppendTo([]int{-1}) if want := []int{-1, 123, 456, 789}; fmt.Sprint(got) != fmt.Sprint(want) { t.Errorf("%s.AppendTo: got %v, want %v", set, got, want) } set.Clear() if set.Len() != 0 { t.Errorf("Clear: got %d, want 0", set.Len()) } if !set.IsEmpty() { t.Errorf("IsEmpty: got false") } if set.Has(123) { t.Errorf("%s.Has: got false", set) } }
// Intersects reports whether this points-to set and the // argument points-to set contain common members. func (x PointsToSet) Intersects(y PointsToSet) bool { if x.pts == nil || y.pts == nil { return false } // This takes Θ(|x|+|y|) time. var z intsets.Sparse z.Intersection(&x.pts.Sparse, &y.pts.Sparse) return !z.IsEmpty() }
func TestIntersects(t *testing.T) { prng := rand.New(rand.NewSource(0)) for i := uint(0); i < 12; i++ { X, Y := randomPset(prng, 1<<i), randomPset(prng, 1<<i) x, y := &X.bits, &Y.bits // test the slow way var z intsets.Sparse z.Copy(x) z.IntersectionWith(y) if got, want := x.Intersects(y), !z.IsEmpty(); got != want { t.Errorf("Intersects: got %v, want %v", got, want) } // make it false a := x.AppendTo(nil) for _, v := range a { y.Remove(v) } if got, want := x.Intersects(y), false; got != want { t.Errorf("Intersects: got %v, want %v", got, want) } // make it true if x.IsEmpty() { continue } i := prng.Intn(len(a)) y.Insert(a[i]) if got, want := x.Intersects(y), true; got != want { t.Errorf("Intersects: got %v, want %v", got, want) } } }
func TestSubsetOf(t *testing.T) { prng := rand.New(rand.NewSource(0)) for i := uint(0); i < 12; i++ { X, Y := randomPset(prng, 1<<i), randomPset(prng, 1<<i) x, y := &X.bits, &Y.bits // test the slow way var z intsets.Sparse z.Copy(x) z.DifferenceWith(y) if got, want := x.SubsetOf(y), z.IsEmpty(); got != want { t.Errorf("SubsetOf: got %v, want %v", got, want) } // make it true y.UnionWith(x) if got, want := x.SubsetOf(y), true; got != want { t.Errorf("SubsetOf: got %v, want %v", got, want) } // make it false if x.IsEmpty() { continue } a := x.AppendTo(nil) i := prng.Intn(len(a)) y.Remove(a[i]) if got, want := x.SubsetOf(y), false; got != want { t.Errorf("SubsetOf: got %v, want %v", got, want) } } }
func (sb *SearchBotT) Search(searchBy map[string]string, searchFor []string, login string, password string, tid string) stonelizard.Response { var providers *intsets.Sparse var searchFields *intsets.Sparse var commonFields *intsets.Sparse var oneShotProviders *intsets.Sparse var field string var isFragmented bool var i int var p *TaxonomyTreeT var hasQueryParm bool var rep chan map[string]ResponseFieldT var response map[string]ResponseFieldT var responses map[string][]ResponseFieldT var respCount int //TODO: Readaptar searchBy["X-Login"] = login searchBy["X-Password"] = password searchBy["X-Trackid"] = tid // Goose.Search = goose.Alert(6) // defer func() { Goose.Search = goose.Alert(2) }() providers = &intsets.Sparse{} Goose.Search.Logf(2, "TID:%s len(sb.Providers): %d", tid, len(sb.Providers)) // Fill the providers set with all provider currently known for i = 0; i < len(sb.Providers); i++ { providers.Insert(i) } // Determine if there is at least one bot providing all data needed // by repeatedly computing providers ∩= 'providers of a given field' for _, field = range searchFor { i, _, p = sb.Taxonomy.Search(field) if ((i + 1) != len(field)) || (p == nil) || (p.Id < 0) { Goose.Search.Logf(1, "TID:%s %s: %s", tid, ErrUndefinedField, field) return stonelizard.Response{ Status: http.StatusInternalServerError, Body: fmt.Sprintf("%s: %s", ErrUndefinedField, field), } } if sb.ByProvision[p.Id] == nil { isFragmented = true break } providers.IntersectionWith(sb.ByProvision[p.Id]) if providers.IsEmpty() { isFragmented = true break } } Goose.Search.Logf(4, "TID:%s Determined if there is at least one bot providing all data needed (isFragmented=%#v): %#v", tid, isFragmented, providers) if !isFragmented { // Select in the bots that have all information needed // those who require only information we have searchFields = &intsets.Sparse{} for field, _ = range searchBy { i, _, p = sb.Taxonomy.Search(field) searchFields.Insert(p.Id) } Goose.Search.Logf(4, "TID:%s Bitstring of search created: %#v", tid, searchFields) oneShotProviders = &intsets.Sparse{} commonFields = &intsets.Sparse{} Goose.Search.Logf(4, "TID:%s providers.Max(): %d", tid, providers.Max()) for i = 0; i <= providers.Max(); i++ { Goose.Search.Logf(4, "TID:%s Bitstring of sb.Providers[%d].Requires: %#v", tid, i, sb.Providers[i].Requires) commonFields.Intersection(searchFields, sb.Providers[i].Requires) if commonFields.Len() == sb.Providers[i].Requires.Len() { Goose.Search.Logf(4, "TID:%s Intersection at %d", tid, i) oneShotProviders.Insert(i) } } Goose.Search.Logf(4, "TID:%s Bitstring of oneShotProviders: %#v", tid, oneShotProviders) // If there is at least one bot who gives all fields // we need and requires just fields we already have... if oneShotProviders.Len() > 0 { rep = make(chan map[string]ResponseFieldT, oneShotProviders.Len()) Goose.Search.Logf(4, "TID:%s len(sb.Providers): %d", tid, len(sb.Providers)) for i = 0; i <= oneShotProviders.Max(); i++ { Goose.Search.Logf(4, "TID:%s oneShotProvider: %d", tid, i) if oneShotProviders.Has(i) { go func(instance int, report chan map[string]ResponseFieldT) { var err error var req *http.Request var host string var path string var swParm stonelizard.SwaggerParameterT var body map[string]interface{} var b_body []byte var resp *http.Response var qryResponse map[string]ResponseFieldT var nHost int // var buf []byte // var n int Goose.Search.Logf(1, "TID:%s searching instance %d: ", tid, instance) defer func() { rep <- qryResponse }() for nHost = 0; nHost < len(sb.Providers[instance].Bot.Host); nHost++ { if sb.Providers[instance].Bot.Listen[0] == ':' { host = sb.Providers[instance].Bot.Host[nHost].Name } else { nHost = len(sb.Providers[instance].Bot.Host) } host = sb.Providers[instance].Operation.Schemes[0] + "://" + host + sb.Providers[instance].Bot.Listen path = sb.Providers[instance].Path body = map[string]interface{}{} Goose.Search.Logf(4, "TID:%s Will add search path=%s, body=%#v", tid, path, body) Goose.Search.Logf(4, "TID:%s Swagger reports the operation parameters are %#v", tid, sb.Providers[instance].Operation.Parameters) hasQueryParm = false for _, swParm = range sb.Providers[instance].Operation.Parameters { Goose.Search.Logf(3, "TID:%s adding search parm: %s", tid, swParm.Name) if swParm.In == "path" { path = strings.Replace(path, "{"+swParm.Name+"}", searchBy[swParm.Name], -1) Goose.Search.Logf(3, "TID:%s path now is: %s", tid, path) } else if swParm.In == "query" { if !hasQueryParm { path += "?" hasQueryParm = true } else { path += "&" } path += swParm.Name + "=" + url.QueryEscape(searchBy[swParm.Name]) Goose.Search.Logf(4, "TID:%s path now is: %#v", tid, path) } else if swParm.In == "body" { body[swParm.Name] = searchBy[swParm.Name] Goose.Search.Logf(4, "TID:%s body now is: %#v", tid, body) } } if sb.Providers[instance].Operation.Consumes[0] == "application/json" { b_body, err = json.Marshal(body) } else if sb.Providers[instance].Operation.Consumes[0] == "application/xml" { b_body, err = xml.Marshal(body) } if err != nil { Goose.Search.Logf(1, "TID:%s %s: %s", tid, ErrMarshalingRequestBody, err) return } Goose.Search.Logf(4, "TID:%s Requesting search via %s:%s%s with body=%#v", tid, sb.Providers[instance].HttpMethod, host, path, body) req, err = http.NewRequest(sb.Providers[instance].HttpMethod, host+path, bytes.NewReader(b_body)) if err != nil { Goose.Search.Logf(1, "%s: %s", ErrAssemblyingRequest, err) return } for _, swParm = range sb.Providers[instance].Operation.Parameters { if swParm.In == "header" { if _, ok := req.Header[swParm.Name]; ok { req.Header[swParm.Name] = append(req.Header[swParm.Name], searchBy[swParm.Name]) } else { req.Header[swParm.Name] = []string{searchBy[swParm.Name]} } // req.Header.Add(swParm.Name,searchBy[swParm.Name]) } } resp, err = sb.HttpsSearchClient.Do(req) if err != nil { Goose.Search.Logf(1, "TID:%s %s: %s", tid, ErrQueryingSearchBot, err) continue // Let's try querying another instance of the search bots } /* if resp.ContentLength > 0 { b_body = make([]byte,resp.ContentLength) err = io.ReadFull(resp.Body,b_body) } else { b_body = make([]byte,bufsz) buf = b_body err = nil for err == nil { n, err = resp.Body.Read(buf) if (n==0) && (err==io.EOF) { break } if (err!=nil) && (err!=io.EOF) { Goose.Search.Logf(1,"TID:%s %s: %s",tid,ErrReadingResponseBody,err) return } if n < bufsz { b_body = b_body[:len(b_body)-(bufsz-n)] break } b_body = append(b_body,...make([]byte,bufsz)) buf = b_body[len(b_body)-bufsz:] } } */ // tmpbody, _ :=ioutil.ReadAll(resp.Body) // Goose.Search.Logf(4,"TID:%s Response: %s",tid,tmpbody) if sb.Providers[instance].Operation.Produces[0] == "application/json" { err = json.NewDecoder(resp.Body).Decode(&body) } else if sb.Providers[instance].Operation.Produces[0] == "application/xml" { err = xml.NewDecoder(resp.Body).Decode(&body) } Goose.Search.Logf(4, "TID:%s Response body: %#v", tid, body) if err != nil { Goose.Search.Logf(1, "TID:%s %s: %s", tid, ErrUnmarshalingRequestBody, err) return } qryResponse = map[string]ResponseFieldT{} for _, fieldName := range searchFor { Goose.Search.Logf(4, "TID:%s fetching Field %s: %#v", tid, fieldName, body[fieldName]) Goose.Search.Logf(7, "TID:%s body[dtupdate]: %#v", tid, body["dtupdate"]) Goose.Search.Logf(7, "TID:%s sb.Providers[instance].BotId: %#v", tid, sb.Providers[instance].BotId) Goose.Search.Logf(7, "TID:%s sb.Providers[instance].Bot.Host[nHost]: %#v", tid, sb.Providers[instance].Bot.Host[nHost]) qryResponse[fieldName] = ResponseFieldT{ Value: body[fieldName], Source: sb.Providers[instance].BotId + "@" + sb.Providers[instance].Bot.Host[nHost].Name, DtUpd: body["DtUpdate"].(string), } } Goose.Search.Logf(4, "TID:%s ResponseFieldT: %#v", tid, qryResponse) break } }(i, rep) } } responses = map[string][]ResponseFieldT{} for respCount < oneShotProviders.Len() { Goose.Search.Logf(4, "TID:%s Waiting response %d/%d", tid, respCount, oneShotProviders.Len()) response = <-rep respCount++ if response != nil { Goose.Search.Logf(4, "TID:%s Got response from bot: %#v", tid, response) for k, v := range response { if _, ok := responses[k]; ok { responses[k] = append(responses[k], v) } else { responses[k] = []ResponseFieldT{v} } } } else { Goose.Search.Logf(1, "TID:%s Bot instance failed", tid) } } Goose.Search.Logf(4, "TID:%s Final consolidated ResponseFieldT: %#v", tid, responses) return stonelizard.Response{ Status: http.StatusOK, Body: responses, } } } /* if !isFragmented { for i=0; i < providers.Max(); i++ { if providers.Has(i) { go func(instance int) { sb.HttpsSearchClient.Get(sb.Providers[i]) }(i) } } } */ return stonelizard.Response{ Status: http.StatusOK, Body: "Unimplemented yet!", } }