Package ariba.util.core

Source Code of ariba.util.core.BatchProcessor

/*
    Copyright 1996-2008 Ariba, Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

    $Id: //ariba/platform/util/core/ariba/util/core/BatchProcessor.java#2 $
*/
package ariba.util.core;

import java.util.Collection;
import java.util.List;
import java.util.SortedSet;

/**
    Convenience class that abstracts the notion of
    processing a collection of objects in chunks of a given size.
    <p/>

    @aribaapi ariba
*/
public abstract class BatchProcessor
{
    /**
        Processes the supplied <code>collection</code>. <p/>

        @throws BatchProcessingException if there is an exception procesing
                <code>collection</code>
        @aribaapi ariba
    */
    public abstract void processBatch (Collection collection)
    throws BatchProcessingException;

    /**
        Represents the position "before the first element" in a collection.
        @aribaapi private
    */
    private static final Object InitialSentinel = new Object();

    /**
        Processes the supplied <code>collection</code> which may be of any size.
        This implementation splits <code>collection</code> up into batches
        and repeatedly calls {@link #processBatch} as necessary. <p/>

        If <code>collection</code> is a <code>List</code>, then this
        method calls {@link #processBatch} with <code>Lists</code>. Similarly
        for <code>SortedSets</code>. <p/>
    
        Each of the calls to
        <code>process()</code> satisfies the following conditions: <ul>
        <li> the size of the collection argument is greater than zero and
             determined by the <code>sizer</code>
        <li> the order of the collection is preserved
        <li> all elements are passed exactly once.
        </ul><p>

        @throws BatchProcessingException if there is an exception procesing
                the batches
        @aribaapi ariba
    */
    public final void process (Collection collection, BatchSizer sizer)
    throws BatchProcessingException
    {
        if (sizer instanceof BatchSizer.Fixed && collection instanceof List) {
            BatchSizer.Fixed fixed = (BatchSizer.Fixed)sizer;
            if (fixed.currentSize() == 0) {
                process((List)collection, fixed.batchSize());
                return;
            }
        }
        SortedSet set = (collection instanceof SortedSet) ? (SortedSet)collection : null;
        List list = (collection instanceof List) ? (List)collection : null;
        List subList = (set == null && list == null) ? ListUtil.list() : null;
        Object begin = InitialSentinel;
        int beginIdx = 0;
        boolean doProcessBatch = false;
        int idx = 0;
        for (Object object : collection)
        {
            if (doProcessBatch) {
                sizer.reset();
                Collection subCollection;
                if (set != null) {
                    subCollection = (begin == InitialSentinel)
                                    ? set.headSet(object)
                                    : set.subSet(begin, object);
                    begin = object;
                }
                else if (list != null) {
                    subCollection = list.subList(beginIdx, idx);
                    beginIdx = idx;
                }
                else {
                    subCollection = subList;
                    subList = ListUtil.list();
                }
                processBatch(subCollection);
            }
            ++idx;
            if (subList != null) {
                subList.add(object);
            }
            doProcessBatch = sizer.addToBatch(object);
        }
        Collection subCollection;
        if (set != null) {
            subCollection = (begin == InitialSentinel) ? set : set.tailSet(begin);
        }
        else if (list != null) {
            subCollection = list.subList(beginIdx, list.size());
        }
        else {
            subCollection = subList;
        }
        if (!subCollection.isEmpty()) {
            processBatch(subCollection);
        }
    }

    /**
        Processes the supplied <code>collection</code> which may be of any size.
        This implementation splits <code>collection</code> up into batches
        and repeatedly calls {@link #processBatch} as necessary. <p/>

        If <code>collection</code> is a <code>List</code>, then this
        method calls {@link #processBatch} with <code>Lists</code>. Similarly
        for <code>SortedSets</code>. <p/>

        Each of the calls to
        <code>process()</code> satisfies the following conditions: <ul>
        <li> the size of the collection argument is greater than zero and less
             than or equal to the batch size
        <li> the order of the collection is preserved
        <li> all elements are passed exactly once.
        </ul><p>

        @throws BatchProcessingException if there is an exception procesing
                the batches
        @aribaapi ariba
    */
    public final void process (Collection collection, int batchSize)
    throws BatchProcessingException
    {
        if (collection instanceof List) {
            process((List)collection, batchSize);
        }
        else {
            process(collection, new BatchSizer.Fixed(batchSize));
        }
    }

    /**
        Processes the supplied <code>list</code> which may be of any size.
        This implementation splits <code>list</code> up into batches
        and repeatedly calls {@link #processBatch} as necessary.
        Each of the calls to
        <code>process()</code> satisfies the following conditions: <ul>
        <li> the size of the list argument is greater than zero and less
             than or equal to the batch size
        <li> the order of the list is preserved
        <li> all elements are passed exactly once.
        </ul><p>

        @throws BatchProcessingException if there is an exception procesing
                the batches
        @aribaapi ariba
    */
    public final void process (List list, int batchSize)
    throws BatchProcessingException
    {
        int remaining = list.size();
        if (remaining <= batchSize) {
            processBatch(list);
        }
        else {
            int startIdx = 0;
            do {
                int length = Math.min(batchSize, remaining);
                List subList = list.subList(startIdx, startIdx + length);
                processBatch(subList);
                remaining -= length;
                startIdx += length;
            }
            while (remaining > 0);
        }
    }
}
TOP

Related Classes of ariba.util.core.BatchProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.