/*
* Copyright (C) 2015
* heaven7(donshine723@gmail.com)
*
* 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.heaven7.scrap.util;
import java.util.ArrayList;
import java.util.Collection;
//comes from android src
/**
* Copy on write array. This array is not thread safe, and only one loop can
* iterate over this array at any given time. This class avoids allocations
* until a concurrent modification happens.
*
* Usage:
*
* CopyOnWriteArray.Access<MyData> access = array.start();
* try {
* for (int i = 0; i < access.size(); i++) {
* MyData d = access.get(i);
* }
* } finally {
* access.end();
* }
*/
public class CopyOnWriteArray<T> {
private ArrayList<T> mData = new ArrayList<T>();
private ArrayList<T> mDataCopy;
private final Access<T> mAccess = new Access<T>();
private boolean mStart;
public static class Access<T> {
private ArrayList<T> mData;
private int mSize;
public T get(int index) {
return mData.get(index);
}
public int size() {
return mSize;
}
}
public CopyOnWriteArray() {
}
private ArrayList<T> getArray() {
if (mStart) {
if (mDataCopy == null) mDataCopy = new ArrayList<T>(mData);
return mDataCopy;
}
return mData;
}
public Access<T> start() {
if (mStart) throw new IllegalStateException("Iteration already started");
mStart = true;
mDataCopy = null;
mAccess.mData = mData;
mAccess.mSize = mData.size();
return mAccess;
}
public void end() {
if (!mStart) throw new IllegalStateException("Iteration not started");
mStart = false;
if (mDataCopy != null) {
mData = mDataCopy;
mAccess.mData.clear();
mAccess.mSize = 0;
}
mDataCopy = null;
}
public int size() {
return getArray().size();
}
public void add(T item) {
getArray().add(item);
}
public void addAll(CopyOnWriteArray<T> array) {
getArray().addAll(array.mData);
}
public void addAll(Collection<T> collection) {
getArray().addAll(collection);
}
public void addAll(T...ts) {
for(T t : ts){
getArray().add(t);
}
}
public void remove(T item) {
getArray().remove(item);
}
public void clear() {
getArray().clear();
}
public boolean contains(Object t){
return getArray().contains(t);
}
}