SUnion returns the members of the set resulting from the union of all the given sets.
(ctx *Context, txn *db.Transaction)
| 156 | |
| 157 | // SUnion returns the members of the set resulting from the union of all the given sets. |
| 158 | func SUnion(ctx *Context, txn *db.Transaction) (OnCommit, error) { |
| 159 | var members [][]byte |
| 160 | var setsIter []*db.SetIter |
| 161 | for _, key := range ctx.Args { |
| 162 | set, err := txn.Set([]byte(key)) |
| 163 | if err != nil { |
| 164 | if err == db.ErrTypeMismatch { |
| 165 | return nil, ErrTypeMismatch |
| 166 | } |
| 167 | return nil, errors.New("ERR " + err.Error()) |
| 168 | } |
| 169 | if !set.Exists() { |
| 170 | continue |
| 171 | } |
| 172 | siter, err := set.Iter() |
| 173 | if err != nil { |
| 174 | return nil, errors.New("ERR " + err.Error()) |
| 175 | } |
| 176 | defer siter.Iter.Close() |
| 177 | setsIter = append(setsIter, siter) |
| 178 | } |
| 179 | |
| 180 | h := MinHeap(setsIter) |
| 181 | heap.Init(&h) |
| 182 | var last []byte |
| 183 | for len(h) != 0 { |
| 184 | min := h[0].Value() |
| 185 | |
| 186 | // ignore the duplicated member |
| 187 | if last == nil || !bytes.Equal(min, last) { |
| 188 | members = append(members, min) |
| 189 | } |
| 190 | last = min |
| 191 | |
| 192 | if err := h[0].Iter.Next(); err != nil { |
| 193 | return nil, err |
| 194 | } |
| 195 | if h[0].Valid() { |
| 196 | heap.Fix(&h, 0) |
| 197 | } else { |
| 198 | heap.Remove(&h, 0) |
| 199 | } |
| 200 | } |
| 201 | return BytesArray(ctx.Out, members), nil |
| 202 | } |
| 203 | |
| 204 | type MinHeap []*db.SetIter |
| 205 |