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

amaembo / streamex / #677

02 Nov 2024 08:50AM UTC coverage: 99.673%. Remained the same
#677

push

amaembo
Optimize imports

5786 of 5805 relevant lines covered (99.67%)

1.0 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, 2024 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.*;
26

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

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

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

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

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

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

146
    @Override
147
    public int characteristics() {
148
        // Remove SORTED, NONNULL, DISTINCT
149
        return left.characteristics() & right.characteristics() & (SIZED | SUBSIZED | ORDERED | IMMUTABLE | CONCURRENT);
1✔
150
    }
151
}
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