/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.timeseries.date.localdate; import java.util.AbstractMap.SimpleImmutableEntry; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.SortedMap; import java.util.concurrent.ConcurrentSkipListMap; import org.threeten.bp.LocalDate; import com.opengamma.timeseries.date.DateObjectTimeSeries; /** * Builder implementation for {@code ImmutableLocalDateObjectTimeSeries}. */ final class ImmutableLocalDateObjectTimeSeriesBuilder<V> implements LocalDateObjectTimeSeriesBuilder<V> { /** * The time-series. */ private SortedMap<Integer, V> _series = new ConcurrentSkipListMap<>(); // use this map to block nulls /** * Creates an instance. */ protected ImmutableLocalDateObjectTimeSeriesBuilder() { } //------------------------------------------------------------------------- private static int convertToInt(LocalDate date) { return LocalDateToIntConverter.convertToInt(date); } private static LocalDate convertFromInt(int date) { return LocalDateToIntConverter.convertToLocalDate(date); } //------------------------------------------------------------------------- @Override public int size() { return _series.size(); } @Override public LocalDateObjectEntryIterator<V> iterator() { return new LocalDateObjectEntryIterator<V>() { private Iterator<Entry<Integer, V>> _iterator = _series.entrySet().iterator(); private int _index = -1; private Entry<Integer, V> _current; @Override public boolean hasNext() { return _iterator.hasNext(); } @Override public Entry<LocalDate, V> next() { return new SimpleImmutableEntry<>(nextTime(), currentValue()); } @Override public int nextTimeFast() { if (hasNext() == false) { throw new NoSuchElementException("No more elements in the iteration"); } _index++; _current = _iterator.next(); return _current.getKey(); } @Override public LocalDate nextTime() { return convertFromInt(nextTimeFast()); } @Override public int currentTimeFast() { if (_index < 0) { throw new IllegalStateException("Iterator has not yet been started"); } if (_current == null) { throw new IllegalStateException("Element has been removed"); } return _current.getKey(); } @Override public LocalDate currentTime() { return convertFromInt(currentTimeFast()); } @Override public V currentValue() { if (_index < 0) { throw new IllegalStateException("Iterator has not yet been started"); } if (_current == null) { throw new IllegalStateException("Element has been removed"); } return _current.getValue(); } @Override public int currentIndex() { return _index; } @Override public void remove() { if (_index < 0) { throw new IllegalStateException("Iterator has not yet been started"); } if (_current == null) { throw new IllegalStateException("Element has been removed"); } _iterator.remove(); _current = null; _index--; } }; } //------------------------------------------------------------------------- @Override public LocalDateObjectTimeSeriesBuilder<V> put(LocalDate time, V value) { return put(convertToInt(time), value); } @Override public LocalDateObjectTimeSeriesBuilder<V> put(int time, V value) { _series.put(time, value); return this; } @Override public LocalDateObjectTimeSeriesBuilder<V> putAll(LocalDate[] times, V[] values) { if (times.length != values.length) { throw new IllegalArgumentException("Arrays are of different sizes: " + times.length + ", " + values.length); } for (int i = 0; i < times.length; i++) { put(times[i], values[i]); } return this; } @Override public LocalDateObjectTimeSeriesBuilder<V> putAll(int[] times, V[] values) { if (times.length != values.length) { throw new IllegalArgumentException("Arrays are of different sizes: " + times.length + ", " + values.length); } for (int i = 0; i < times.length; i++) { put(times[i], values[i]); } return this; } //------------------------------------------------------------------------- @Override public LocalDateObjectTimeSeriesBuilder<V> putAll(DateObjectTimeSeries<?, V> timeSeries) { return putAll(timeSeries, 0, timeSeries.size()); } @Override public LocalDateObjectTimeSeriesBuilder<V> putAll(DateObjectTimeSeries<?, V> timeSeries, int startPos, int endPos) { if (startPos < 0 || startPos > timeSeries.size()) { throw new IndexOutOfBoundsException("Invalid start index: " + startPos); } if (endPos < 0 || endPos > timeSeries.size()) { throw new IndexOutOfBoundsException("Invalid end index: " + endPos); } if (startPos > endPos) { throw new IndexOutOfBoundsException("End index not be less than start index"); } if (startPos == endPos) { return this; } for (int i = startPos; i < endPos; i++) { put(timeSeries.getTimeAtIndexFast(i), timeSeries.getValueAtIndex(i)); } return this; } @Override public LocalDateObjectTimeSeriesBuilder<V> putAll(Map<LocalDate, V> timeSeriesMap) { if (timeSeriesMap.size() == 0) { return this; } for (Entry<LocalDate, V> entry : timeSeriesMap.entrySet()) { put(entry.getKey(), entry.getValue()); } return this; } //------------------------------------------------------------------------- @Override public LocalDateObjectTimeSeriesBuilder<V> clear() { _series.clear(); return this; } //------------------------------------------------------------------------- @Override public ImmutableLocalDateObjectTimeSeries<V> build() { int[] times = new int[_series.size()]; @SuppressWarnings("unchecked") V[] values = (V[]) new Object[_series.size()]; int i = 0; for (Entry<Integer, V> entry : _series.entrySet()) { times[i] = entry.getKey(); values[i++] = entry.getValue(); } return new ImmutableLocalDateObjectTimeSeries<V>(times, values); } //------------------------------------------------------------------------- @Override public String toString() { return "Builder[size=" + _series.size() + "]"; } }