Search in sources :

Example 16 with Range

use of com.vaadin.flow.internal.Range in project flow by vaadin.

the class HierarchyMapperWithDataTest method fetchWithFilter.

@Test
public void fetchWithFilter() {
    expand(testData.get(0));
    // Expand second node
    Node expandedNode = testData.get(2 + LEAF_COUNT);
    expand(expandedNode);
    SerializablePredicate<Node> filter = n -> n.getNumber() % 2 == 0;
    // Root nodes plus children of expanded nodes 0 and 4 that match the
    // filter
    List<Node> expectedResult = IntStream.of(0, 1, 4, 6, 7, 10, 13, 26, 39, 52).mapToObj(testData::get).collect(Collectors.toList());
    mapper.setFilter(filter);
    // Fetch everything
    Range range = Range.between(0, mapper.getTreeSize());
    verifyFetchIsCorrect(expectedResult, range);
}
Also used : IntStream(java.util.stream.IntStream) Arrays(java.util.Arrays) Collection(java.util.Collection) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) Objects(java.util.Objects) List(java.util.List) Stream(java.util.stream.Stream) Rule(org.junit.Rule) SerializablePredicate(com.vaadin.flow.function.SerializablePredicate) Comparator(java.util.Comparator) Assert(org.junit.Assert) ExpectedException(org.junit.rules.ExpectedException) Assert.assertEquals(org.junit.Assert.assertEquals) Before(org.junit.Before) Range(com.vaadin.flow.internal.Range) Range(com.vaadin.flow.internal.Range) Test(org.junit.Test)

Example 17 with Range

use of com.vaadin.flow.internal.Range in project flow by vaadin.

the class DataCommunicator method collectKeysToFlush.

private Activation collectKeysToFlush(final Range previousActive, final Range effectiveRequested) {
    /*
         * Collecting all items even though only some small sub range would
         * actually be useful can be optimized away once we have some actual
         * test coverage for the logic here.
         */
    if (resendEntireRange) {
        return activate(effectiveRequested);
    } else {
        List<String> newActiveKeyOrder = new ArrayList<>();
        boolean sizeRecheckNeeded = false;
        Range[] partitionWith = effectiveRequested.partitionWith(previousActive);
        Activation activation = activate(partitionWith[0]);
        newActiveKeyOrder.addAll(activation.getActiveKeys());
        sizeRecheckNeeded |= activation.isSizeRecheckNeeded();
        // Pick existing items from the current list
        Range overlap = partitionWith[1].offsetBy(-activeStart);
        if (overlap.getStart() < 0) {
            // needs to be returned
            return Activation.empty();
        }
        newActiveKeyOrder.addAll(activeKeyOrder.subList(overlap.getStart(), overlap.getEnd()));
        activation = activate(partitionWith[2]);
        newActiveKeyOrder.addAll(activation.getActiveKeys());
        sizeRecheckNeeded |= activation.isSizeRecheckNeeded();
        return new Activation(newActiveKeyOrder, sizeRecheckNeeded);
    }
}
Also used : ArrayList(java.util.ArrayList) Range(com.vaadin.flow.internal.Range)

Example 18 with Range

use of com.vaadin.flow.internal.Range in project flow by vaadin.

the class DataCommunicator method fetchFromProvider.

/**
 * Fetches a list of items from the DataProvider.
 * <p>
 * <em>NOTE:</em> the {@code limit} parameter shows how many items the
 * client wants to fetch, but the actual number of results may be greater,
 * and vary from {@code 0 to pages * pageSize}.
 *
 * @param offset
 *            the starting index of the range
 * @param limit
 *            the desired number of results
 * @return the list of items in given range
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
protected Stream<T> fetchFromProvider(int offset, int limit) {
    Stream<T> stream;
    if (pagingEnabled) {
        /*
             * Items limit value may not be necessarily multiply of page size,
             * and thus the pages count is rounded to closest smallest integer
             * in order to overlap the requested range. Integer division is used
             * here for simplicity and to avoid double-int-double conversion.
             * Divisor minus one is placed on numerator part to ensure upwards
             * rounding.
             */
        final int pages = (limit - 1) / pageSize + 1;
        if (limit > pageSize) {
            /*
                 * Requested range is split to several pages, and queried from
                 * backend page by page
                 */
            final Stream.Builder<T> streamBuilder = Stream.builder();
            final AtomicInteger fetchedPerPage = new AtomicInteger(0);
            Consumer<T> addItemAndCheckConsumer = item -> {
                streamBuilder.add(item);
                fetchedPerPage.getAndIncrement();
            };
            // Keep fetching the pages until we get empty/partial page,
            // or run out of pages to request
            int page = 0;
            do {
                final int newOffset = offset + page * pageSize;
                doFetchFromDataProvider(newOffset, pageSize).forEach(addItemAndCheckConsumer);
                page++;
            } while (page < pages && fetchedPerPage.getAndSet(0) == pageSize);
            stream = streamBuilder.build();
        } else {
            stream = doFetchFromDataProvider(offset, pageSize);
        }
        limit = pages * pageSize;
    } else {
        stream = doFetchFromDataProvider(offset, limit);
    }
    if (stream.isParallel()) {
        getLogger().debug("Data provider {} has returned parallel stream on 'fetch' call", getDataProvider().getClass());
        stream = stream.collect(Collectors.toList()).stream();
        assert !stream.isParallel();
    }
    SizeVerifier verifier = new SizeVerifier<>(limit);
    return stream.peek(verifier);
}
Also used : NodeOwner(com.vaadin.flow.internal.NodeOwner) ExecutionContext(com.vaadin.flow.internal.ExecutionContext) SerializableComparator(com.vaadin.flow.function.SerializableComparator) Component(com.vaadin.flow.component.Component) BiFunction(java.util.function.BiFunction) ComponentUtil(com.vaadin.flow.component.ComponentUtil) Registration(com.vaadin.flow.shared.Registration) LoggerFactory(org.slf4j.LoggerFactory) Json(elemental.json.Json) JsonArray(elemental.json.JsonArray) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) StateTree(com.vaadin.flow.internal.StateTree) SerializableConsumer(com.vaadin.flow.function.SerializableConsumer) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) JsonValue(elemental.json.JsonValue) PushMode(com.vaadin.flow.shared.communication.PushMode) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Element(com.vaadin.flow.dom.Element) Update(com.vaadin.flow.data.provider.ArrayUpdater.Update) DataRefreshEvent(com.vaadin.flow.data.provider.DataChangeEvent.DataRefreshEvent) UI(com.vaadin.flow.component.UI) Range(com.vaadin.flow.internal.Range) StateNode(com.vaadin.flow.internal.StateNode) Logger(org.slf4j.Logger) Executor(java.util.concurrent.Executor) Set(java.util.Set) SerializableSupplier(com.vaadin.flow.function.SerializableSupplier) Collectors(java.util.stream.Collectors) Serializable(java.io.Serializable) Objects(java.util.Objects) Consumer(java.util.function.Consumer) List(java.util.List) JsonUtils(com.vaadin.flow.internal.JsonUtils) Stream(java.util.stream.Stream) Optional(java.util.Optional) JsonObject(elemental.json.JsonObject) Comparator(java.util.Comparator) Collections(java.util.Collections) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Stream(java.util.stream.Stream)

Example 19 with Range

use of com.vaadin.flow.internal.Range in project flow by vaadin.

the class HierarchicalCommunicationController method collectKeysToFlush.

private List<String> collectKeysToFlush(final Range previousActive, final Range effectiveRequested) {
    List<String> newActiveKeyOrder;
    /*
         * Collecting all items even though only some small sub range would
         * actually be useful can be optimized away once we have some actual
         * test coverage for the logic here.
         */
    if (resendEntireRange) {
        newActiveKeyOrder = activate(effectiveRequested);
    } else {
        Range[] partitionWith = effectiveRequested.partitionWith(previousActive);
        newActiveKeyOrder = new ArrayList<>();
        newActiveKeyOrder.addAll(activate(partitionWith[0]));
        // Pick existing items from the current list
        Range overlap = partitionWith[1].offsetBy(-activeStart);
        newActiveKeyOrder.addAll(activeKeyOrder.subList(overlap.getStart(), overlap.getEnd()));
        newActiveKeyOrder.addAll(activate(partitionWith[2]));
    }
    return newActiveKeyOrder;
}
Also used : Range(com.vaadin.flow.internal.Range)

Example 20 with Range

use of com.vaadin.flow.internal.Range in project flow by vaadin.

the class HierarchicalCommunicationController method flush.

public void flush() {
    Set<String> oldActive = new HashSet<>(activeKeyOrder);
    assumedSize = mapper.countChildItems(keyMapper.get(parentKey));
    final Range previousActive = Range.withLength(activeStart, activeKeyOrder.size());
    final Range effectiveRequested = requestedRange.restrictTo(Range.withLength(0, assumedSize));
    resendEntireRange |= !(previousActive.intersects(effectiveRequested) || (previousActive.isEmpty() && effectiveRequested.isEmpty()));
    // Phase 1: Find all items that the client should have
    List<String> newActiveKeyOrder = collectKeysToFlush(previousActive, effectiveRequested);
    activeKeyOrder = newActiveKeyOrder;
    activeStart = effectiveRequested.getStart();
    // Phase 2: Collect changes to send
    HierarchicalUpdate update = startUpdate.apply(assumedSize);
    boolean updated = collectChangesToSend(previousActive, effectiveRequested, update);
    resendEntireRange = false;
    assumeEmptyClient = false;
    // Phase 3: passivate anything that isn't longer active
    passivateInactiveKeys(oldActive, newActiveKeyOrder, update, updated);
    // Phase 4: unregister passivated and updated items
    unregisterPassivatedKeys();
}
Also used : HierarchicalUpdate(com.vaadin.flow.data.provider.hierarchy.HierarchicalArrayUpdater.HierarchicalUpdate) Range(com.vaadin.flow.internal.Range) HashSet(java.util.HashSet)

Aggregations

Range (com.vaadin.flow.internal.Range)33 Test (org.junit.Test)28 ArrayList (java.util.ArrayList)5 Comparator (java.util.Comparator)4 List (java.util.List)4 Objects (java.util.Objects)4 Collectors (java.util.stream.Collectors)4 Stream (java.util.stream.Stream)4 SerializablePredicate (com.vaadin.flow.function.SerializablePredicate)3 Arrays (java.util.Arrays)3 Collection (java.util.Collection)3 HashSet (java.util.HashSet)3 UI (com.vaadin.flow.component.UI)2 IntStream (java.util.stream.IntStream)2 Assert (org.junit.Assert)2 Assert.assertEquals (org.junit.Assert.assertEquals)2 Assert.assertTrue (org.junit.Assert.assertTrue)2 Before (org.junit.Before)2 Rule (org.junit.Rule)2 ExpectedException (org.junit.rules.ExpectedException)2