HCOLL-159 moved net.openhft.chronicle.hash.threadlocal package to Lang since it isn't specific to ChronicleMap at all

This commit is contained in:
leventov
2014-10-29 16:11:21 +03:00
parent 70fdbb1fc6
commit f7edfce81b
13 changed files with 16 additions and 203 deletions
@@ -18,9 +18,9 @@
package net.openhft.chronicle.hash.serialization;
import net.openhft.chronicle.hash.threadlocal.Provider;
import net.openhft.chronicle.hash.threadlocal.StatefulCopyable;
import net.openhft.chronicle.hash.threadlocal.ThreadLocalCopies;
import net.openhft.lang.threadlocal.Provider;
import net.openhft.lang.threadlocal.StatefulCopyable;
import net.openhft.lang.threadlocal.ThreadLocalCopies;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.DirectBytes;
import net.openhft.lang.io.DirectStore;
@@ -18,7 +18,7 @@
package net.openhft.chronicle.hash.serialization;
import net.openhft.chronicle.hash.threadlocal.ThreadLocalCopies;
import net.openhft.lang.threadlocal.ThreadLocalCopies;
import java.io.ObjectStreamException;
@@ -18,7 +18,7 @@
package net.openhft.chronicle.hash.serialization;
import net.openhft.chronicle.hash.threadlocal.ThreadLocalCopies;
import net.openhft.lang.threadlocal.ThreadLocalCopies;
import java.io.Serializable;
@@ -22,7 +22,7 @@ import net.openhft.chronicle.hash.serialization.BytesReader;
import net.openhft.lang.io.AbstractBytes;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.pool.CharSequenceInterner;
import net.openhft.chronicle.hash.threadlocal.StatefulCopyable;
import net.openhft.lang.threadlocal.StatefulCopyable;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
@@ -1,87 +0,0 @@
/*
* Copyright 2014 Higher Frequency Trading
*
* http://www.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.chronicle.hash.threadlocal;
public abstract class Provider<T> {
public static <T> Provider<T> of(Class<T> tClass) {
if (StatefulCopyable.class.isAssignableFrom(tClass)) {
return StatefulProvider.INSTANCE;
}
return StatelessProvider.INSTANCE;
}
public abstract T get(ThreadLocalCopies copies, T original);
public abstract ThreadLocalCopies getCopies(ThreadLocalCopies copies);
private static final class StatefulProvider<T extends StatefulCopyable<T>> extends Provider<T> {
private static final Provider INSTANCE = new StatefulProvider();
@Override
public ThreadLocalCopies getCopies(ThreadLocalCopies copies) {
if (copies != null)
return copies;
return ThreadLocalCopies.get();
}
@Override
public T get(ThreadLocalCopies copies, T original) {
if (copies.currentlyAccessed.compareAndSet(false, true)) {
Object id = original.stateIdentity();
int m = copies.mask;
Object[] tab = copies.table;
int i = System.identityHashCode(id) & m;
T copy;
while (true) {
Object idInTable = tab[i];
if (idInTable == id) {
copy = (T) tab[i + 1];
break;
} else if (idInTable == null) {
tab[i] = id;
tab[i + 1] = copy = original.copy();
copies.postInsert();
break;
}
i = (i + 2) & m;
}
copies.currentlyAccessed.set(false);
return copy;
} else {
throw new IllegalStateException(
"Concurrent or recursive access to ThreadLocalCopies is not allowed");
}
}
}
private static final class StatelessProvider<M> extends Provider<M> {
private static final Provider INSTANCE = new StatelessProvider();
@Override
public M get(ThreadLocalCopies copies, M original) {
return original;
}
@Override
public ThreadLocalCopies getCopies(ThreadLocalCopies copies) {
return copies;
}
}
}
@@ -1,25 +0,0 @@
/*
* Copyright 2014 Higher Frequency Trading
*
* http://www.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.chronicle.hash.threadlocal;
public interface StatefulCopyable<S extends StatefulCopyable<S>> {
Object stateIdentity();
S copy();
}
@@ -1,75 +0,0 @@
/*
* Copyright 2014 Higher Frequency Trading
*
* http://www.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.chronicle.hash.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();
}
};
static ThreadLocalCopies get() {
return states.get();
}
AtomicBoolean currentlyAccessed = new AtomicBoolean(false);
Object[] table;
int size = 0, sizeLimit, mask;
private ThreadLocalCopies() {
init(32); // 16 entries
}
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();
}
}
@@ -22,8 +22,8 @@ import net.openhft.chronicle.hash.*;
import net.openhft.chronicle.hash.serialization.MetaBytesInterop;
import net.openhft.chronicle.hash.serialization.MetaBytesWriter;
import net.openhft.chronicle.hash.serialization.MetaProvider;
import net.openhft.chronicle.hash.threadlocal.Provider;
import net.openhft.chronicle.hash.threadlocal.ThreadLocalCopies;
import net.openhft.lang.threadlocal.Provider;
import net.openhft.lang.threadlocal.ThreadLocalCopies;
import net.openhft.chronicle.set.ChronicleSetBuilder;
import net.openhft.lang.Maths;
import net.openhft.lang.io.ByteBufferBytes;
@@ -23,7 +23,7 @@ import net.openhft.chronicle.hash.TimeProvider;
import net.openhft.chronicle.hash.serialization.BytesReader;
import net.openhft.chronicle.hash.serialization.MetaBytesInterop;
import net.openhft.chronicle.hash.serialization.MetaBytesWriter;
import net.openhft.chronicle.hash.threadlocal.ThreadLocalCopies;
import net.openhft.lang.threadlocal.ThreadLocalCopies;
import net.openhft.lang.Maths;
import net.openhft.lang.collection.ATSDirectBitSet;
import net.openhft.lang.io.Bytes;
@@ -18,8 +18,8 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.threadlocal.Provider;
import net.openhft.chronicle.hash.threadlocal.ThreadLocalCopies;
import net.openhft.lang.threadlocal.Provider;
import net.openhft.lang.threadlocal.ThreadLocalCopies;
import net.openhft.chronicle.hash.serialization.*;
import net.openhft.chronicle.hash.serialization.impl.*;
import net.openhft.lang.io.Bytes;
@@ -18,8 +18,8 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.threadlocal.Provider;
import net.openhft.chronicle.hash.threadlocal.ThreadLocalCopies;
import net.openhft.lang.threadlocal.Provider;
import net.openhft.lang.threadlocal.ThreadLocalCopies;
import net.openhft.chronicle.hash.serialization.*;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.model.Byteable;
@@ -20,8 +20,8 @@ package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.ChronicleHashErrorListener;
import net.openhft.chronicle.hash.serialization.*;
import net.openhft.chronicle.hash.threadlocal.Provider;
import net.openhft.chronicle.hash.threadlocal.ThreadLocalCopies;
import net.openhft.lang.threadlocal.Provider;
import net.openhft.lang.threadlocal.ThreadLocalCopies;
import net.openhft.lang.collection.DirectBitSet;
import net.openhft.lang.collection.SingleThreadedDirectBitSet;
import net.openhft.lang.io.*;