Index returns a list of items that match on the index function Index is thread-safe so long as you treat all items as immutable
(indexName string, obj interface{})
| 134 | // Index returns a list of items that match on the index function |
| 135 | // Index is thread-safe so long as you treat all items as immutable |
| 136 | func (c *threadSafeMap) Index(indexName string, obj interface{}) ([]interface{}, error) { |
| 137 | c.lock.RLock() |
| 138 | defer c.lock.RUnlock() |
| 139 | |
| 140 | indexFunc := c.indexers[indexName] |
| 141 | if indexFunc == nil { |
| 142 | return nil, fmt.Errorf("Index with name %s does not exist", indexName) |
| 143 | } |
| 144 | |
| 145 | indexKeys, err := indexFunc(obj) |
| 146 | if err != nil { |
| 147 | return nil, err |
| 148 | } |
| 149 | index := c.indices[indexName] |
| 150 | |
| 151 | var returnKeySet sets.String |
| 152 | if len(indexKeys) == 1 { |
| 153 | // In majority of cases, there is exactly one value matching. |
| 154 | // Optimize the most common path - deduping is not needed here. |
| 155 | returnKeySet = index[indexKeys[0]] |
| 156 | } else { |
| 157 | // Need to de-dupe the return list. |
| 158 | // Since multiple keys are allowed, this can happen. |
| 159 | returnKeySet = sets.String{} |
| 160 | for _, indexKey := range indexKeys { |
| 161 | for key := range index[indexKey] { |
| 162 | returnKeySet.Insert(key) |
| 163 | } |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | list := make([]interface{}, 0, returnKeySet.Len()) |
| 168 | for absoluteKey := range returnKeySet { |
| 169 | list = append(list, c.items[absoluteKey]) |
| 170 | } |
| 171 | return list, nil |
| 172 | } |
| 173 | |
| 174 | // ByIndex returns a list of items that match an exact value on the index function |
| 175 | func (c *threadSafeMap) ByIndex(indexName, indexKey string) ([]interface{}, error) { |