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

drv.StripedOpenHashMap.drv Maven / Gradle / Ivy

Go to download

fastutil extends the Java Collections Framework by providing type-specific maps, sets, lists, and queues with a small memory footprint and fast operations; it provides also big (64-bit) arrays, sets, and lists, sorting algorithms, fast, practical I/O classes for binary and text files, and facilities for memory mapping large files. This jar (fastutil-core.jar) contains data structures based on integers, longs, doubles, and objects, only; fastutil.jar contains all classes. If you have both jars in your dependencies, this jar should be excluded.

The newest version!
/*
 * Copyright (C) 2002-2022 Sebastiano Vigna
 *
 * 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 PACKAGE;

import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;

import java.io.Serializable;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

/** A concurrent counting map. The map is made by a number of stripes (instances of {@link Object2IntOpenHashMap})
 * which are accessed independently
 * using a {@link ReentrantReadWriteLock}. Only one thread can write in a stripe at a time, but different stripes
 * can be modified independently and read access can happen concurrently on each stripe.
 *
 * 

The collection view methods ({@link #entrySet()} and similar} are currently not supported, and will throw * {@link UnsupportedOperationException} * * @param the type of keys. */ public class STRIPED_OPEN_HASH_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP KEY_VALUE_GENERIC implements java.io.Serializable, Cloneable { private static final long serialVersionUID = 1L; /** The stripes. Keys are distributed among them using the lower bits of their {@link Object#hashCode()}. */ private final OPEN_HASH_MAP KEY_VALUE_GENERIC[] map; /** An array of locks parallel to {@link #map}, protecting each stripe. */ private final transient ReentrantReadWriteLock[] lock; /** {@link #map map.length} − 1, cached. */ private final int mask; /** Creates a new concurrent counting map with concurrency level equal to {@link Runtime#availableProcessors()}. */ public STRIPED_OPEN_HASH_MAP() { this(Runtime.getRuntime().availableProcessors()); } /** Creates a new concurrent counting map. * * @param concurrencyLevel the number of stripes (it will be {@linkplain Integer#highestOneBit(int) forced to be a power of two}); ideally, as large as the number of threads that will ever access * this map, but higher values require more space. */ SUPPRESS_WARNINGS_KEY_UNCHECKED public STRIPED_OPEN_HASH_MAP(final int concurrencyLevel) { map = new OPEN_HASH_MAP[Integer.highestOneBit(concurrencyLevel)]; lock = new ReentrantReadWriteLock[map.length]; for(int i = map.length; i-- != 0;) { map[i] = new OPEN_HASH_MAP KEY_VALUE_GENERIC_DIAMOND(); lock[i] = new ReentrantReadWriteLock(); } mask = map.length - 1; } #if KEYS_PRIMITIVE public VALUE_GENERIC_CLASS get(final KEY_CLASS k) { final int stripe = KEY2INTHASH(k) & mask; final ReadLock readLock = lock[stripe].readLock(); try { readLock.lock(); return map[stripe].get(k); } finally { readLock.unlock(); } } #endif SUPPRESS_WARNINGS_KEY_UNCHECKED public VALUE_GENERIC_TYPE GET_VALUE(final KEY_TYPE k) { final int stripe = KEY2INTHASH(k) & mask; final ReadLock readLock = lock[stripe].readLock(); try { readLock.lock(); return map[stripe].GET_VALUE(k); } finally { readLock.unlock(); } } public VALUE_GENERIC_TYPE put(final KEY_GENERIC_TYPE k, final VALUE_GENERIC_TYPE v) { final int stripe = KEY2INTHASH(k) & mask; final WriteLock writeLock = lock[stripe].writeLock(); try { writeLock.lock(); return map[stripe].put(k, v); } finally { writeLock.unlock(); } } public VALUE_GENERIC_TYPE putIfAbsent(final KEY_GENERIC_TYPE k, final VALUE_GENERIC_TYPE v) { final int stripe = KEY2INTHASH(k) & mask; final WriteLock writeLock = lock[stripe].writeLock(); try { writeLock.lock(); if (map[stripe].containsKey(k)) return map[stripe].get(k); return map[stripe].put(k, v); } finally { writeLock.unlock(); } } #if VALUES_PRIMITIVE || KEYS_PRIMITIVE public VALUE_GENERIC_CLASS put(final KEY_GENERIC_CLASS ok, final VALUE_GENERIC_CLASS ov) { final int stripe = KEY2INTHASH(ok) & mask; final WriteLock writeLock = lock[stripe].writeLock(); try { writeLock.lock(); return map[stripe].put(ok, ov); } finally { writeLock.unlock(); } } public VALUE_GENERIC_CLASS putIfAbsent(final KEY_GENERIC_CLASS ok, final VALUE_GENERIC_CLASS ov) { final int stripe = KEY2INTHASH(ok) & mask; final WriteLock writeLock = lock[stripe].writeLock(); try { writeLock.lock(); if (map[stripe].containsKey(ok)) return map[stripe].get(ok); return map[stripe].put(ok, ov); } finally { writeLock.unlock(); } } #endif public int size() { int size = 0; for(int stripe = lock.length; stripe-- != 0;) { final ReadLock readLock = lock[stripe].readLock(); try { readLock.lock(); size += map[stripe].size(); } finally { readLock.unlock(); } } return size; } public FastEntrySet KEY_VALUE_GENERIC ENTRYSET() { throw new UnsupportedOperationException(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy