vigna / fastutil

fastutil extends the Java™ Collections Framework by providing type-specific maps, sets, lists and queues.
Apache License 2.0
1.8k stars 197 forks source link

Spliterators.concat.characteristics() should never return SORTED or DISTINCT even if all sub-spliterators do. #190

Closed techsy730 closed 3 years ago

techsy730 commented 3 years ago

The SORTED and DISTINCT property do not combine. For example: (assume there is a hypothetical SortedSet.of, which there isn't at the time of this writing)

IntSortedSet s1 = IntSortedSet.of(1,2,3);
IntSortedSet s2 = IntSortedSet.of(1,4,6);
IntSpliterator split1 = s1.spliterator();
IntSpliterator split2 = s2.spliterator();
IntSpliterator combined = IntSpliterators.concat(split1, split2);

Now both split1 and split2 report NONNULL | SIZED | ORDERED | SORTED | DISTINCT as their characteristics. As such, so does the combined spliterator. But the combined spliterator will give the elements {1, 2, 3, 1, 4, 6}, and that is neither SORTED nor DISTINCT.

The fix is to make Spliterators.SpliteratorConcatenator#computeCharacteristics never set the SORTED or DISTINCT bits even if all child spliterators do.

vigna commented 3 years ago

What does the JDK do?

techsy730 commented 3 years ago

The JDK actually had none of Iterator, Spliterator, or Stream concatenation functions. Guava does have Stream concatenation; I am taking a look at what they do now.

techsy730 commented 3 years ago

Ok, so what Guava does is to only allow ORDERED | SIZED | NONNULL to be reported by the underlying concat'ed spliterator, and only if all sub-spliterators do as well.

I think that may be too restrictive for us (this implementation will correctly handle SUBSIZED for example).

vigna commented 3 years ago

I'd let you decide which properties filter to the concatenation—you wrote the code...