github.com/m3db/m3@v1.5.0/src/m3ninx/index/segment/mem/concurrent_postings_map_test.go (about) 1 // Copyright (c) 2018 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package mem 22 23 import ( 24 "regexp" 25 "sort" 26 "testing" 27 28 sgmt "github.com/m3db/m3/src/m3ninx/index/segment" 29 30 "github.com/stretchr/testify/require" 31 ) 32 33 func TestConcurrentPostingsMap(t *testing.T) { 34 opts := NewOptions() 35 pm := newConcurrentPostingsMap(opts) 36 37 pm.Add([]byte("foo"), 1) 38 pm.Add([]byte("bar"), 2) 39 pm.Add([]byte("foo"), 3) 40 pm.Add([]byte("baz"), 4) 41 42 pl, ok := pm.Get([]byte("foo")) 43 require.True(t, ok) 44 require.Equal(t, 2, pl.Len()) 45 require.True(t, pl.Contains(1)) 46 require.True(t, pl.Contains(3)) 47 48 _, ok = pm.Get([]byte("fizz")) 49 require.False(t, ok) 50 51 re := regexp.MustCompile("ba.*") 52 pl, ok = pm.GetRegex(re) 53 require.True(t, ok) 54 require.Equal(t, 2, pl.Len()) 55 require.True(t, pl.Contains(2)) 56 require.True(t, pl.Contains(4)) 57 58 re = regexp.MustCompile("abc.*") 59 _, ok = pm.GetRegex(re) 60 require.False(t, ok) 61 } 62 63 func TestConcurrentPostingsMapKeys(t *testing.T) { 64 opts := NewOptions() 65 pm := newConcurrentPostingsMap(opts) 66 67 keys := toTermPostings(t, pm.Keys()) 68 require.Empty(t, keys) 69 70 var ( 71 foo = []byte("foo") 72 bar = []byte("bar") 73 baz = []byte("baz") 74 ) 75 76 pm.Add(foo, 1) 77 78 keys = toTermPostings(t, pm.Keys()) 79 require.Equal(t, termPostings{"foo": []int{1}}, keys) 80 81 pm.Add(bar, 2) 82 keys = toTermPostings(t, pm.Keys()) 83 require.Equal(t, termPostings{"bar": []int{2}, "foo": []int{1}}, keys) 84 85 pm.Add(foo, 3) 86 keys = toTermPostings(t, pm.Keys()) 87 require.Equal(t, termPostings{"bar": []int{2}, "foo": []int{1, 3}}, keys) 88 89 pm.Add(baz, 4) 90 keys = toTermPostings(t, pm.Keys()) 91 require.Equal(t, termPostings{"bar": []int{2}, "foo": []int{1, 3}, "baz": []int{4}}, keys) 92 } 93 94 type termPostings map[string][]int 95 96 func toTermPostings(t *testing.T, iter sgmt.TermsIterator) termPostings { 97 elems := make(termPostings) 98 for iter.Next() { 99 term, postings := iter.Current() 100 _, exists := elems[string(term)] 101 require.False(t, exists) 102 103 values := []int{} 104 it := postings.Iterator() 105 for it.Next() { 106 values = append(values, int(it.Current())) 107 } 108 sort.Sort(sort.IntSlice(values)) 109 110 require.NoError(t, it.Err()) 111 require.NoError(t, it.Close()) 112 113 elems[string(term)] = values 114 } 115 require.NoError(t, iter.Err()) 116 require.NoError(t, iter.Close()) 117 return elems 118 }