001 /*
002 * Java Genetic Algorithm Library (jenetics-7.1.0).
003 * Copyright (c) 2007-2022 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019 */
020 package io.jenetics.prog.regression;
021
022 import java.util.Arrays;
023 import java.util.Collection;
024 import java.util.Iterator;
025
026 /**
027 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
028 * @version 6.0
029 * @since 6.0
030 */
031 final class RingBuffer {
032
033 private final Object[] _buffer;
034
035 private int _cursor = -1;
036 private int _size = 0;
037
038 private Object[] _snapshot = null;
039
040 RingBuffer(final int capacity) {
041 if (capacity < 1) {
042 throw new IllegalArgumentException(
043 "Buffer size must be a positive: " + capacity
044 );
045 }
046
047 _buffer = new Object[capacity];
048 }
049
050 synchronized void add(final Object element) {
051 _buffer[next()] = element;
052 _snapshot = null;
053 }
054
055 private int next() {
056 if (_size < _buffer.length) {
057 ++_size;
058 }
059 return _cursor = (_cursor + 1 < _buffer.length) ? _cursor + 1 : 0;
060 }
061
062 synchronized void addAll(final Collection<?> elements) {
063 final Iterator<?> it = elements.iterator();
064 if (elements.size() > capacity()) {
065 for (int i = capacity(); i < elements.size(); ++i) {
066 it.next();
067 }
068 }
069
070 while (it.hasNext()) {
071 _buffer[next()] = it.next();
072 }
073 _snapshot = null;
074 }
075
076 synchronized Object[] snapshot() {
077 if (_snapshot != null) {
078 return _snapshot;
079 }
080
081 final Object[] result = new Object[_size];
082 if (_size < _buffer.length) {
083 System.arraycopy(_buffer, 0, result, 0, _size);
084 } else {
085 System.arraycopy(
086 _buffer, _cursor + 1,
087 result, 0, _buffer.length - _cursor - 1
088 );
089 System.arraycopy(
090 _buffer, 0,
091 result, _buffer.length - _cursor - 1, _cursor + 1
092 );
093 }
094
095 return _snapshot = result;
096 }
097
098 /**
099 * Removes all the elements from {@code this} ring-buffer. The buffer
100 * will be empty after this method returns.
101 */
102 void clear() {
103 Arrays.fill(_buffer, null);
104 _cursor = -1;
105 _size = 0;
106 _snapshot = null;
107 }
108
109 /**
110 * Return the capacity of {@code this} ring-buffer.
111 *
112 * @return the capacity of {@code this} ring-buffers
113 */
114 int capacity() {
115 return _buffer.length;
116 }
117
118 /**
119 * Return the size of {@code this} ring-buffer, where {@code size <= capacity}
120 * is always true.
121 *
122 * @return the capacity of {@code this} ring-buffers
123 */
124 int size() {
125 return _size;
126 }
127 }
|