• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

amaembo / streamex / #667

02 Sep 2023 01:21PM UTC coverage: 99.462% (-0.2%) from 99.619%
#667

push

amaembo
One more test for Limiter

5733 of 5764 relevant lines covered (99.46%)

0.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.68
/src/main/java/one/util/streamex/ZipSpliterator.java
1
/*
2
 * Copyright 2015, 2019 StreamEx contributors
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package one.util.streamex;
17

18
import java.util.Spliterator;
19
import java.util.Spliterators;
20
import java.util.function.BiFunction;
21
import java.util.function.Consumer;
22

23
import static one.util.streamex.Internals.Box;
24
import static one.util.streamex.Internals.drainTo;
25
import static one.util.streamex.UnknownSizeSpliterator.BATCH_UNIT;
26
import static one.util.streamex.UnknownSizeSpliterator.MAX_BATCH;
27
import static one.util.streamex.UnknownSizeSpliterator.USOfRef;
28

29
/**
30
 * @author Tagir Valeev
31
 */
32
/* package */class ZipSpliterator<U, V, R> implements Spliterator<R> {
33
    private Spliterator<U> left;
34
    private Spliterator<V> right;
35
    private final BiFunction<? super U, ? super V, ? extends R> mapper;
36
    private boolean trySplit;
37
    private int batch = 0;
1✔
38
    private final Box<U> l = new Box<>();
1✔
39
    private final Box<V> r = new Box<>();
1✔
40

41
    ZipSpliterator(Spliterator<U> left, Spliterator<V> right, BiFunction<? super U, ? super V, ? extends R> mapper, boolean trySplit) {
1✔
42
        this.left = left;
1✔
43
        this.right = right;
1✔
44
        this.mapper = mapper;
1✔
45
        this.trySplit = trySplit;
1✔
46
    }
1✔
47

48
    @Override
49
    public boolean tryAdvance(Consumer<? super R> action) {
50
        if (left.tryAdvance(l) && right.tryAdvance(r)) {
1✔
51
            action.accept(mapper.apply(l.a, r.a));
1✔
52
            return true;
1✔
53
        }
54
        return false;
1✔
55
    }
56

57
    @Override
58
    public void forEachRemaining(Consumer<? super R> action) {
59
        if (!hasCharacteristics(SIZED)) {
1✔
60
            Spliterator.super.forEachRemaining(action);
1✔
61
            return;
1✔
62
        }
63
        long leftSize = left.getExactSizeIfKnown();
1✔
64
        long rightSize = right.getExactSizeIfKnown();
1✔
65
        if (leftSize <= rightSize) {
1✔
66
            left.forEachRemaining(u -> {
1✔
67
                if (right.tryAdvance(r)) {
1✔
68
                    action.accept(mapper.apply(u, r.a));
1✔
69
                }
70
            });
1✔
71
        } else {
72
            right.forEachRemaining(v -> {
1✔
73
                if (left.tryAdvance(l)) {
1✔
74
                    action.accept(mapper.apply(l.a, v));
1✔
75
                }
76
            });
1✔
77
        }
78
    }
1✔
79

80
    @Override
81
    public Spliterator<R> trySplit() {
82
        if (trySplit && hasCharacteristics(SIZED | SUBSIZED)) {
1✔
83
            Spliterator<U> leftPrefix = left.trySplit();
1✔
84
            if (leftPrefix == null)
1✔
85
                return arraySplit();
1✔
86
            Spliterator<V> rightPrefix = right.trySplit();
1✔
87
            if (rightPrefix == null) {
1✔
88
                left = new TailConcatSpliterator<>(leftPrefix, left);
1✔
89
                return arraySplit();
1✔
90
            }
91
            long leftSize = leftPrefix.getExactSizeIfKnown();
1✔
92
            long rightSize = rightPrefix.getExactSizeIfKnown();
1✔
93
            if (leftSize >= 0 && rightSize >= 0) {
1✔
94
                if (leftSize == rightSize) {
1✔
95
                    return new ZipSpliterator<>(leftPrefix, rightPrefix, mapper, true);
1✔
96
                }
97
                if (Math.abs(leftSize - rightSize) < Math.min(BATCH_UNIT, Math.max(leftSize, rightSize) / 8)) {
1✔
98
                    if (leftSize < rightSize) {
1✔
99
                        @SuppressWarnings("unchecked")
100
                        U[] array = (U[]) new Object[(int) (rightSize - leftSize)];
1✔
101
                        drainTo(array, left);
1✔
102
                        leftPrefix = new TailConcatSpliterator<>(leftPrefix, Spliterators.spliterator(array, characteristics()));
1✔
103
                    } else {
1✔
104
                        @SuppressWarnings("unchecked")
105
                        V[] array = (V[]) new Object[(int) (leftSize - rightSize)];
1✔
106
                        drainTo(array, right);
1✔
107
                        rightPrefix = new TailConcatSpliterator<>(rightPrefix, Spliterators.spliterator(array, characteristics()));
1✔
108
                    }
109
                    this.trySplit = false;
1✔
110
                    return new ZipSpliterator<>(leftPrefix, rightPrefix, mapper, false);
1✔
111
                }
112
            }
113
            left = new TailConcatSpliterator<>(leftPrefix, left);
1✔
114
            right = new TailConcatSpliterator<>(rightPrefix, right);
1✔
115
        }
116
        return arraySplit();
1✔
117
    }
118
    
119
    private Spliterator<R> arraySplit() {
120
        long s = estimateSize();
1✔
121
        if (s <= 1) return null;
1✔
122
        int n = batch + BATCH_UNIT;
1✔
123
        if (n > s)
1✔
124
            n = (int) s;
1✔
125
        if (n > MAX_BATCH)
1✔
126
            n = MAX_BATCH;
×
127
        @SuppressWarnings("unchecked")
128
        R[] array = (R[]) new Object[n];
1✔
129
        int index = drainTo(array, this);
1✔
130
        if ((batch = index) == 0)
1✔
131
            return null;
1✔
132
        long s2 = estimateSize();
1✔
133
        USOfRef<R> prefix = new UnknownSizeSpliterator.USOfRef<>(array, 0, index);
1✔
134
        if (hasCharacteristics(SUBSIZED))
1✔
135
            prefix.est = index;
1✔
136
        else if (s == s2)
1✔
137
            prefix.est = Math.max(index, s / 2);
1✔
138
        else
139
            prefix.est = Math.max(index, s2 - s);
1✔
140
        return prefix;
1✔
141
    }
142

143
    @Override
144
    public long estimateSize() {
145
        return Math.min(left.estimateSize(), right.estimateSize());
1✔
146
    }
147

148
    @Override
149
    public int characteristics() {
150
        // Remove SORTED, NONNULL, DISTINCT
151
        return left.characteristics() & right.characteristics() & (SIZED | SUBSIZED | ORDERED | IMMUTABLE | CONCURRENT);
1✔
152
    }
153
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc