Skip to content
This repository has been archived by the owner on Aug 23, 2023. It is now read-only.

Commit

Permalink
get intersection of multiple tag queries
Browse files Browse the repository at this point in the history
  • Loading branch information
replay committed Sep 15, 2017
1 parent 7648336 commit d375fb9
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 16 deletions.
41 changes: 27 additions & 14 deletions idx/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,14 @@ func (m *MemoryIdx) addTags(def *schema.MetricDefinition) {
continue
}

if _, ok = tags[tagSplits[0]]; !ok {
tags[tagSplits[0]] = make(map[string][]string)
tagName := tagSplits[0]
tagValue := tagSplits[1]

if _, ok = tags[tagName]; !ok {
tags[tagName] = make(map[string][]string)
}

tags[tagSplits[0]][tagSplits[1]] = append(tags[tagSplits[0]][tagSplits[1]], def.Name)
tags[tagName][tagValue] = append(tags[tagName][tagValue], def.Name)
}
}

Expand Down Expand Up @@ -322,25 +325,35 @@ func (m *MemoryIdx) IdsByTagQuery(orgId int, query tag.TagQuery) []string {
}

func (m *MemoryIdx) idsByTagQuery(tags map[string]map[string][]string, query tag.TagQuery) []string {
idSet := make(map[string]struct{})
for _, expression := range query.Expressions {
for _, id := range m.idsByTagExpression(tags, expression) {
idSet[id] = struct{}{}
var intersection map[string]struct{}

// lot of room to optimize this intersect, just making it work for now
for expI, expression := range query.Expressions {
ids := m.idsByTagExpression(tags, expression)
if expI == 0 {
intersection = ids
continue
}

for id := range intersection {
if _, ok := ids[id]; !ok {
delete(intersection, id)
}
}
}

ids := make([]string, 0, len(idSet))
for id, _ := range idSet {
ids = append(ids, id)
results := make([]string, 0, len(intersection))
for id := range intersection {
results = append(results, id)
}

return ids
return results
}

func (m *MemoryIdx) idsByTagExpression(tags map[string]map[string][]string, expr tag.TagExpression) []string {
var results []string
func (m *MemoryIdx) idsByTagExpression(tags map[string]map[string][]string, expr tag.TagExpression) map[string]struct{} {
var keyValues map[string][]string
var ok bool
results := make(map[string]struct{})

if keyValues, ok = tags[expr.Key]; !ok {
return results
Expand All @@ -350,7 +363,7 @@ func (m *MemoryIdx) idsByTagExpression(tags map[string]map[string][]string, expr
for value, ids := range keyValues {
if ev(value) {
for _, id := range ids {
results = append(results, id)
results[id] = struct{}{}
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions idx/memory/memory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -561,14 +561,16 @@ func TestGetByTag(t *testing.T) {
[]string{"key1=~value[23]"},
[]string{"key1=value1", "key2=value1"},
[]string{"key1=value1", "key2=value2"},
[]string{"key1=~value[12]", "key2=value2"},
[]string{"key1=~value1", "key1=value2"},
}
expecting := []int{3, 1, 3, 4, 1, 3, 4}
expecting := []int{3, 1, 3, 4, 1, 0, 1, 2, 0}

for i := 0; i < len(expecting); i++ {
tagQuery := tag.NewTagQuery(expressions[i])
res := ix.IdsByTagQuery(1, *tagQuery)
if len(res) != expecting[i] {
t.Fatal(fmt.Sprintf("Expected %d int test %d results, but got %d: %q", expecting[i], i, len(res), res))
t.Fatal(fmt.Sprintf("Expected %d in test %d results, but got %d: %q", expecting[i], i, len(res), res))
}
}
}
Expand Down

0 comments on commit d375fb9

Please sign in to comment.