All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xenoamess.commons.primitive.iterators.AbstractLongSpliterator Maven / Gradle / Ivy

There is a newer version: 0.13.1
Show newest version
/*
 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.xenoamess.commons.primitive.iterators;

import com.xenoamess.commons.primitive.Primitive;
import com.xenoamess.commons.primitive.functions.LongConsumer;

/**
 * An abstract {@code LongSpliterator.LongOfLong} that implements
 * {@code trySplit} to permit limited parallelism.
 *
 * 

To implement a spliterator an extending class need only * implement {@link #tryAdvance(LongConsumer) * tryAdvance}. The extending class should override * {@link #forEachRemaining(LongConsumer) forEachRemaining} * if it can provide a more performant implementation. * * @author XenoAmess * @version 0.8.0 * @apiNote This class is a useful aid for creating a spliterator when it is not * possible or difficult to efficiently partition elements in a manner * allowing balanced parallel computation. * *

An alternative to using this class, that also permits limited * parallelism, is to create a spliterator from an iterator * (see {@link com.xenoamess.commons.primitive.iterators.LongSpliterators#spliterator(LongIterator, long, int)}. * Depending on the circumstances using an iterator may be easier or more * convenient than extending this class. For example, if there is already an * iterator available to use then there is no need to extend this class. * @see LongSpliterators#spliterator(LongIterator, long, int) * @since 1.8 */ public abstract class AbstractLongSpliterator implements LongSpliterator.LongOfLong, Primitive { static final int MAX_BATCH = 1 << 10; static final int BATCH_UNIT = 1 << 25; private final int characteristics; private long est; // size estimate private int batch; // batch size for splits /** * Creates a spliterator reporting the given estimated size and * characteristics. * * @param est the estimated size of this spliterator if known, otherwise * {@code Long.MAX_VALUE}. * @param additionalCharacteristics properties of this spliterator's * source or elements. If {@code SIZED} is reported then this * spliterator will additionally report {@code SUBSIZED}. */ protected AbstractLongSpliterator(long est, int additionalCharacteristics) { this.est = est; this.characteristics = ((additionalCharacteristics & LongSpliterator.SIZED) != 0) ? additionalCharacteristics | LongSpliterator.SUBSIZED : additionalCharacteristics; } static final class HoldingLongConsumer implements LongConsumer { long value; @Override public void acceptPrimitive(long value) { this.value = value; } } /** * {@inheritDoc} *

* This implementation permits limited parallelism. */ @Override public LongSpliterator.LongOfLong trySplit() { HoldingLongConsumer holder = new HoldingLongConsumer(); long s = est; if (s > 1 && tryAdvance(holder)) { int n = batch + BATCH_UNIT; if (n > s) { n = (int) s; } if (n > MAX_BATCH) { n = MAX_BATCH; } long[] a = new long[n]; int j = 0; do { a[j] = holder.value; } while (++j < n && tryAdvance(holder)); batch = j; if (est != Long.MAX_VALUE) { est -= j; } return new LongArraySpliterator(a, 0, j, characteristics()); } return null; } /** * {@inheritDoc} * * @implSpec This implementation returns the estimated size as reported when * created and, if the estimate size is known, decreases in size when * split. */ @Override public long estimateSize() { return est; } /** * {@inheritDoc} * * @implSpec This implementation returns the characteristics as reported when * created. */ @Override public int characteristics() { return characteristics; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy