| 181 | } |
| 182 | |
| 183 | func (it *Iterator) Next(ctx context.Context) bool { |
| 184 | if it.offset+1 < len(it.buffer) { |
| 185 | it.offset++ |
| 186 | it.result = &Token{Kind: it.kind, Hash: it.buffer[it.offset]} |
| 187 | return true |
| 188 | } |
| 189 | if it.done { |
| 190 | return false |
| 191 | } |
| 192 | // Reset buffer and offset |
| 193 | it.offset = 0 |
| 194 | it.buffer = make([]string, 0, bufferSize) |
| 195 | // Create query |
| 196 | // TODO (panamafrancis) Keys only query? |
| 197 | q := datastore.NewQuery(it.kind).Limit(bufferSize) |
| 198 | if !it.isAll { |
| 199 | // Filter on the direction {subject,objekt...} |
| 200 | q = q.Filter(it.dir.String()+" =", it.name) |
| 201 | } |
| 202 | // Get last cursor position |
| 203 | cursor, err := datastore.DecodeCursor(it.last) |
| 204 | if err == nil { |
| 205 | q = q.Start(cursor) |
| 206 | } |
| 207 | // Buffer the keys of the next 50 matches |
| 208 | t := q.Run(it.qs.context) |
| 209 | for { |
| 210 | // Quirk of the datastore, you cannot pass a nil value to to Next() |
| 211 | // even if you just want the keys |
| 212 | var k *datastore.Key |
| 213 | skip := false |
| 214 | if it.kind == quadKind { |
| 215 | temp := new(QuadEntry) |
| 216 | k, err = t.Next(temp) |
| 217 | // Skip if quad has been deleted |
| 218 | if len(temp.Added) <= len(temp.Deleted) { |
| 219 | skip = true |
| 220 | } |
| 221 | } else { |
| 222 | temp := new(NodeEntry) |
| 223 | k, err = t.Next(temp) |
| 224 | // Skip if node has been deleted |
| 225 | if temp.Size == 0 { |
| 226 | skip = true |
| 227 | } |
| 228 | } |
| 229 | if err == datastore.Done { |
| 230 | it.done = true |
| 231 | break |
| 232 | } |
| 233 | if err != nil { |
| 234 | clog.Errorf("Error fetching next entry %v", err) |
| 235 | it.err = err |
| 236 | return false |
| 237 | } |
| 238 | if !skip { |
| 239 | it.buffer = append(it.buffer, k.StringID()) |
| 240 | } |