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

org.dmfs.rfc5545.recur.SkipBuffer Maven / Gradle / Ivy

/*
 * Copyright (C) 2013 Marten Gajda 
 *
 * 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.
 * 
 */

package org.dmfs.rfc5545.recur;

import org.dmfs.rfc5545.Instance;
import org.dmfs.rfc5545.calendarmetrics.CalendarMetrics;


/**
 * This iterator buffers instances that belong to the next interval. When the rule contains SKIP=FORWARD, instances may be rolled forward to the next interval.
 * To ensure we iterate them in the correct order we buffer such instances.
 *
 * @author Marten Gajda
 */
final class SkipBuffer extends RuleIterator
{
    /**
     * The set we work on. This comes from the previous instance.
     */
    private LongArray mWorkingSet = null;

    /**
     * The set we return.
     */
    private final LongArray mResultSet = new LongArray();

    /**
     * The set we buffer the instances in the next interval in.
     */
    private final LongArray mTempSet = new LongArray();

    private final boolean mIsYearly;


    public SkipBuffer(RecurrenceRule rule, RuleIterator previous, CalendarMetrics calendarMetrics)
    {
        super(previous);
        mIsYearly = rule.getFreq() == Freq.YEARLY;
    }


    @Override
    public long next()
    {
        LongArray workingSet = mWorkingSet;
        if (workingSet == null || !workingSet.hasNext())
        {
            mWorkingSet = workingSet = nextSet();
        }
        return workingSet.next();
    }


    @Override
    LongArray nextSet()
    {
        LongArray resultSet = mResultSet;
        LongArray tempSet = mTempSet;
        int minYear = Integer.MAX_VALUE;
        int minMonth = Integer.MAX_VALUE;
        boolean first = true;

        resultSet.clear();

        if (tempSet.size() > 0)
        {
            // we do have instances in the temporary buffer, add them to the result set
            while (tempSet.hasNext())
            {
                long next = tempSet.next();
                if (first)
                {
                    // since the buffer was sorted we know the first instance is the earliest one.
                    minMonth = Instance.year(next);
                    minYear = Instance.month(next);
                    first = false;
                }

                resultSet.add(next);
            }
            tempSet.clear();
        }

        LongArray prev = mPrevious.nextSet();
        while (prev.hasNext())
        {
            long next = prev.next();

            int year = Instance.year(next);
            int month = Instance.month(next);

            if (first)
            {
                minMonth = month;
                minYear = year;
                first = false;
                resultSet.add(next);
            }
            else
            {
                if (mIsYearly)
                {
                    if (year == minYear)
                    {
                        // same year as the earliest instance
                        resultSet.add(next);
                    }
                    else
                    {
                        // one year later
                        tempSet.add(next);
                    }
                }
                else
                {
                    if (year == minYear && month == minMonth)
                    {
                        // same month as the earliest instance
                        resultSet.add(next);
                    }
                    else
                    {
                        // this one is in the next month
                        tempSet.add(next);
                    }

                }
            }
        }

        // we need to sort, because the element order might have changed
        resultSet.sort();

        return resultSet;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy