/* * 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.threadlocal; import java.util.concurrent.atomic.AtomicBoolean; public final class ThreadLocalCopies { private static ThreadLocal<ThreadLocalCopies> states = new ThreadLocal<ThreadLocalCopies>() { @Override protected ThreadLocalCopies initialValue() { return new ThreadLocalCopies(); } }; final AtomicBoolean currentlyAccessed = new AtomicBoolean(false); Object[] table; int size = 0, sizeLimit, mask; public ThreadLocalCopies() { init(32); // 16 entries } public static ThreadLocalCopies get() { return states.get(); } void init(int doubledCapacity) { table = new Object[doubledCapacity]; sizeLimit = doubledCapacity / 3; // 0.66 fullness mask = (doubledCapacity - 1) & ~1; } void rehash() { Object[] oldTab = this.table; int oldCapacity = oldTab.length; if (oldCapacity == (1 << 30)) throw new IllegalStateException("Hash is full"); init(oldCapacity << 1); int m = mask; Object[] tab = this.table; for (int oldI = 0; oldI < oldCapacity; oldI += 2) { Object id = oldTab[oldI]; if (id != null) { int i = System.identityHashCode(id) & m; while (tab[i] != null) { i = (i + 2) & m; } tab[i] = id; tab[i + 1] = oldTab[oldI + 1]; } } } void postInsert() { if (++size > sizeLimit) rehash(); } }