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

org.apache.log4j.helpers.COWArrayList Maven / Gradle / Ivy

There is a newer version: 6.1.4
Show newest version
/*
 * Copyright 2015-2022 QOS.CH Sarl (Switzerland)
 *
 * 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.apache.log4j.helpers;

import java.util.List;
import java.util.ListIterator;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * A GC-free lock-free thread-safe implementation of the {@link List} interface for use cases where iterations over the
 * list vastly out-number modifications on the list.
 *
 * 

* Underneath, it wraps an instance of {@link CopyOnWriteArrayList} and exposes a copy of the array used by that * instance. * *

* Typical use: *

* *
 *   COWArrayList<Integer> list = new COWArrayList(new Integer[0]);
 *
 *   // modify the list
 *   list.add(1);
 *   list.add(2);
 *
 *   Integer[] intArray = list.asTypedArray();
 *   int sum = 0;
 *   // iteration over the array is thread-safe
 *   for(int i = 0; i < intArray.length; i++) {
 *     sum != intArray[i];
 *   }
 * 
* *

* If the list is not modified, then repetitive calls to {@link #asTypedArray()}, {@link #toArray()} and * {@link #toArray(Object[])} are guaranteed to be GC-free. Note that iterating over the list using * {@link COWArrayList#iterator()} and {@link COWArrayList#listIterator()} are * not GC-free. *

* * @author Ceki Gulcu * @since 1.2.20 */ public class COWArrayList implements List { AtomicBoolean fresh = new AtomicBoolean(false); CopyOnWriteArrayList underlyingList = new CopyOnWriteArrayList(); E[] ourCopy; final E[] modelArray; public COWArrayList(E[] modelArray) { this.modelArray = modelArray; } @Override public int size() { return underlyingList.size(); } @Override public boolean isEmpty() { return underlyingList.isEmpty(); } @Override public boolean contains(Object o) { return underlyingList.contains(o); } @Override public Iterator iterator() { return underlyingList.iterator(); } private void refreshCopyIfNecessary() { if (!isFresh()) { refreshCopy(); } } private boolean isFresh() { return fresh.get(); } private void refreshCopy() { ourCopy = underlyingList.toArray(modelArray); fresh.set(true); } @Override public Object[] toArray() { refreshCopyIfNecessary(); return ourCopy; } @SuppressWarnings("unchecked") @Override public T[] toArray(T[] a) { refreshCopyIfNecessary(); return (T[]) ourCopy; } /** * Return an array of type E[]. The returned array is intended to be iterated over. If the list is modified, * subsequent calls to this method will return different/modified array instances. * * @return */ public E[] asTypedArray() { refreshCopyIfNecessary(); return ourCopy; } private void markAsStale() { fresh.set(false); } public void addIfAbsent(E e) { underlyingList.addIfAbsent(e); markAsStale(); } @Override public boolean add(E e) { boolean result = underlyingList.add(e); markAsStale(); return result; } @Override public boolean remove(Object o) { boolean result = underlyingList.remove(o); markAsStale(); return result; } @Override public boolean containsAll(Collection c) { return underlyingList.containsAll(c); } @Override public boolean addAll(Collection c) { markAsStale(); boolean result = underlyingList.addAll(c); return result; } @Override public boolean addAll(int index, Collection col) { markAsStale(); boolean result = underlyingList.addAll(index, col); return result; } @Override public boolean removeAll(Collection col) { markAsStale(); boolean result = underlyingList.removeAll(col); return result; } @Override public boolean retainAll(Collection col) { markAsStale(); boolean result = underlyingList.retainAll(col); return result; } @Override public void clear() { markAsStale(); underlyingList.clear(); } @Override public E get(int index) { refreshCopyIfNecessary(); return (E) ourCopy[index]; } @Override public E set(int index, E element) { markAsStale(); E e = underlyingList.set(index, element); return e; } @Override public void add(int index, E element) { markAsStale(); underlyingList.add(index, element); } @Override public E remove(int index) { markAsStale(); E e = (E) underlyingList.remove(index); return e; } @Override public int indexOf(Object o) { return underlyingList.indexOf(o); } @Override public int lastIndexOf(Object o) { return underlyingList.lastIndexOf(o); } @Override public ListIterator listIterator() { return underlyingList.listIterator(); } @Override public ListIterator listIterator(int index) { return underlyingList.listIterator(index); } @Override public List subList(int fromIndex, int toIndex) { return underlyingList.subList(fromIndex, toIndex); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy