package org.opendaylight.mdsal.binding.dom.adapter.query;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import com.google.common.base.Stopwatch;
import java.util.List;
+import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNull;
import org.junit.AfterClass;
import org.junit.Before;
final List<? extends Item<@NonNull Alarms>> items = execute(query).getItems();
assertEquals(2, items.size());
+
+ List<Alarms> verifiedResult = items.stream()
+ .map(Item::object)
+ .filter(object -> object.getId().equals(Uint64.ZERO))
+ .collect(Collectors.toList());
+ assertNotNull(verifiedResult);
+ assertEquals(2, verifiedResult.size());
}
@Test
}
@SuppressFBWarnings(value = "NP_NONNULL_RETURN_VIOLATION", justification = "Ungrokked @Nullable")
+ // TODO: this is a huge method which could be restructured with hard tailcalls, alas we do not have those (yet?)
+ // Any such refactor better have some benchmarks to show non-regression.
private @Nullable Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> findNext() {
- // We always start with non-empty frames, as we signal end of data when we reach the end. We know this never
- // null, by Eclipse insists. We do not care (that much) and use a poll() here.
- // TODO: this is a huge method which could be restructured with hard tailcalls, alas we do not have those (yet?)
- // Any such refactor better have some benchmarks to show non-regression.
+ // We always start with non-empty frames, as we signal end of data when we reach the end. 'currentPath' points
+ // to the next frame to process.
+
+ // We know this is never null and would have preferred to use pop(), but Eclipse insists. We do not care
+ // (that much) and use a poll() here.
Frame current = frames.poll();
while (current != null) {
+ // Whenever we reach here, 'currentPath' points to the 'current' entry, while 'frames' has current's parent
+ // on top. Every 'continue' site in this block is expected to maintain that invariant.
+ // Furthermore all 'return' sites are expected to leave 'frames' and 'currentPath' consistent, otherwise
+ // next invocation of this method would violate this invariant.
+
+ // Look what's next in the 'select' part of the lookup
final PathArgument next = remainingSelect.poll();
if (next == null) {
// We are matching this frame, and if we got here it must have a stashed iterator, as we deal with
continue;
}
- // Push our state back, it's just a placeholder for 'currentSelect'. Current path points at us and so does
- // the saved Frame.
- currentPath.addLast(current.data.getIdentifier());
-
// Now decide what sort of entry to push. For maps we want to start an iterator already, so it gets
// picked up as a continuation.
if (child instanceof MapNode) {
frames.push(current);
currentPath.addLast(map.getIdentifier());
frames.push(new Frame(map, next));
+ currentPath.addLast(target);
current = new Frame(entry, target);
continue;
}
// We have a wildcard, expand it
frames.push(current);
+ currentPath.addLast(next);
current = new MapFrame(child, next, map.getValue().iterator());
} else {
// Next step in iteration, deal with it
frames.push(current);
+ currentPath.addLast(child.getIdentifier());
current = new Frame(child, next);
}
}