/* * Copyright 2016 higherfrequencytrading.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 net.openhft.lang.collection.impl; import net.openhft.lang.collection.HugeArray; import net.openhft.lang.io.DirectBytes; import net.openhft.lang.io.DirectStore; import net.openhft.lang.model.Byteable; import net.openhft.lang.model.Copyable; import net.openhft.lang.model.DataValueClasses; import java.util.ArrayList; import java.util.List; /** * User: peter.lawrey Date: 08/10/13 Time: 08:11 */ public class HugeArrayImpl<T> implements HugeArray<T> { private static final int MAX_SIZE = 10; private final Class<T> tClass; private final long length; private final int size; private final DirectStore store; private final List<T> freeList = new ArrayList<T>(MAX_SIZE); public HugeArrayImpl(Class<T> tClass, long length) { this.tClass = tClass; this.length = length; T ref = DataValueClasses.newDirectReference(tClass); size = ((Byteable) ref).maxSize(); store = DirectStore.allocate(length * size); ((Byteable) ref).bytes(store.bytes(), 0L); recycle(ref); } private T createRef() { T ref = DataValueClasses.newDirectReference(tClass); ((Byteable) ref).bytes(store.bytes(), 0L); return ref; } @Override public long length() { return length; } @Override public T get(long index) { T t = acquire(); Byteable byteable = (Byteable) t; DirectBytes bytes = (DirectBytes) byteable.bytes(); bytes.positionAndSize(index * size, size); return t; } @Override public void get(long index, T element) { if (tClass.isInstance(element)) { DirectBytes bytes = (DirectBytes) ((Byteable) element).bytes(); bytes.positionAndSize(index * size, size); return; } T t = acquire(); DirectBytes bytes = (DirectBytes) ((Byteable) t).bytes(); bytes.positionAndSize(index * size, size); ((Copyable) element).copyFrom(t); recycle(t); } private T acquire() { int size = freeList.size(); if (size > 0) return freeList.remove(size - 1); return createRef(); } @Override public void copyTo(long index, T to) { T from = get(index); ((Copyable<T>) to).copyFrom(from); recycle(from); } @Override public void set(long index, T from) { T to = get(index); ((Copyable<T>) to).copyFrom(from); recycle(to); } @Override public void recycle(T t) { if (freeList.size() < MAX_SIZE) { assert ((DirectBytes) ((Byteable) t).bytes()).store() == store; assert !freeList.contains(t) : "recycling object already recycled"; freeList.add(t); } } }