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

com.github.jnthnclt.os.lab.collections.baph.ConcurrentBAPHash Maven / Gradle / Ivy

There is a newer version: 1.12.2
Show newest version
package com.github.jnthnclt.os.lab.collections.baph;

import com.github.jnthnclt.os.lab.collections.KeyValueStream;
import java.util.function.BiFunction;
import java.util.function.Function;

/**
 *
 * @author jonathan.colt
 */
public class ConcurrentBAPHash {

    private final int capacity;
    private final boolean hasValues;
    private final BAPHasher hasher;
    private final BAPHash[] hmaps;
    private final BAPReader reader;

    @SuppressWarnings("unchecked")
    public ConcurrentBAPHash(int capacity, boolean hasValues, int concurrency, BAPReader reader) {
        this.capacity = capacity;
        this.hasValues = hasValues;
        this.hasher = BAPHasher.SINGLETON;
        this.hmaps = new BAPHash[concurrency];
        this.reader = reader;
    }

    public void put(long keyPointer, byte[] key, V value) throws Exception {
        int hashCode = hasher.hashCode(key, 0, key.length);
        BAPHash hmap = hmap(hashCode, true);
        synchronized (hmap) {
            hmap.put(hashCode, keyPointer, key, value);
        }
    }

    private BAPHash hmap(int hashCode, boolean create) {
        int index = Math.abs((hashCode) % hmaps.length);
        if (hmaps[index] == null && create) {
            synchronized (hmaps) {
                if (hmaps[index] == null) {
                    hmaps[index] = new BAPHash<>(new BAPHMapState<>(capacity, hasValues, BAPHMapState.NIL_POINTER, BAPHMapState.NIL, reader), hasher,
                        BAPHEqualer.SINGLETON);
                }
            }
        }
        return hmaps[index];
    }

    public int hashCode(byte[] key, int offset, int length) {
        return hasher.hashCode(key, offset, length);
    }

    public V computeIfAbsent(long keyPointer, byte[] key, Function mappingFunction) throws Exception {
        int hashCode = hasher.hashCode(key, 0, key.length);
        return computeIfAbsent(hashCode, keyPointer, key, mappingFunction);
    }

    public V computeIfAbsent(int hashCode, long keyPointer, byte[] key, Function mappingFunction) throws Exception {
        BAPHash< V> hmap = hmap(hashCode, true);
        synchronized (hmap) {
            V value = hmap.get(hashCode, key, 0, key.length);
            if (value == null) {
                value = mappingFunction.apply(key);
                hmap.put(hashCode, key, value);
            }
            return value;
        }
    }

    public V compute(byte[] key, BiFunction remappingFunction) throws Exception {
        int hashCode = hasher.hashCode(key, 0, key.length);
        return compute(hashCode, key, remappingFunction);
    }

    public V compute(int hashCode, byte[] key, BiFunction remappingFunction) throws Exception {
        BAPHash hmap = hmap(hashCode, true);
        synchronized (hmap) {
            V value = hmap.get(hashCode, key, 0, key.length);
            V remapped = remappingFunction.apply(key, value);
            if (remapped != value) {
                value = remapped;
                hmap.put(hashCode, key, value);
            }
            return value;
        }
    }

    public V get(byte[] key) throws Exception {
        return get(key, 0, key.length);
    }

    public V get(byte[] key, int keyOffset, int keyLength) throws Exception {
        int hashCode = hasher.hashCode(key, keyOffset, keyLength);
        return get(hashCode, key, keyOffset, keyLength);
    }

    public V get(int hashCode, byte[] key, int keyOffset, int keyLength) throws Exception {
        BAPHash hmap = hmap(hashCode, false);
        if (hmap != null) {
            synchronized (hmap) {
                return hmap.get(hashCode, key, keyOffset, keyLength);
            }
        }
        return null;
    }

    public void remove(byte[] key) throws Exception {
        remove(key, 0, key.length);
    }

    public void remove(byte[] key, int keyOffset, int keyLength) throws Exception {
        int hashCode = hasher.hashCode(key, keyOffset, keyLength);
        remove(hashCode, key, keyOffset, keyLength);
    }

    public void remove(int hashCode, byte[] key, int keyOffset, int keyLength) throws Exception {
        BAPHash< V> hmap = hmap(hashCode, false);
        if (hmap != null) {
            synchronized (hmap) {
                hmap.remove(hashCode, key, keyOffset, keyLength);
            }
        }
    }

    public void clear() {
        for (BAPHash< V> hmap : hmaps) {
            if (hmap != null) {
                synchronized (hmap) {
                    hmap.clear();
                }
            }
        }
    }

    public int size() {
        int size = 0;
        for (BAPHash hmap : hmaps) {
            if (hmap != null) {
                size += hmap.size();
            }
        }
        return size;
    }

    public boolean stream(KeyValueStream keyValueStream) throws Exception {
        for (BAPHash hmap : hmaps) {
            if (hmap != null) {
                if (!hmap.stream(keyValueStream)) {
                    return false;
                }
            }
        }
        return true;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy