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

org.simpleflatmapper.map.context.impl.KeyObjectStore Maven / Gradle / Ivy

Go to download

Java library to map flat record - ResultSet, csv - to java object with minimum configuration and low footprint.

There is a newer version: 9.0.2
Show newest version
package org.simpleflatmapper.map.context.impl;

import org.simpleflatmapper.map.context.Key;

import java.util.Arrays;

public final class KeyObjectStore {

    private static final int DEFAULT_SIZE = 16;
    private static final int MAXIMUM_CAPACITY = 1 << 30;

    private Key[] keys;
    private Object[] values;
    private int size;
    private int nbValues;
    private int resizeThreshold;
    private int mask;

    public KeyObjectStore() {
        nbValues = 0;
        initSize(DEFAULT_SIZE);
    }

    private int calculateMask(int size) {
        return size - 1;
    }

    public void put(Key key, Object value) {
        checkCapacity();

        int index = getIndex(key);

        if (index >= 0) {
            throw new IllegalArgumentException("Already has key " + key);
        }

        setValue(key, value, index + size);
    }

    private void checkCapacity() {
        if (nbValues > resizeThreshold) resize();
    }


    public Object get(Key key) {
        int index = getIndex(key);

        if (index >= 0) {
            return getValue(index);
        }
        return null;
    }

    private void setValue(Key key, Object value, int index) {
        keys[index] = key;
        values[index] = value;
        nbValues++;
    }

    private Object getValue(int index) {
        return values[index];
    }

    private int getIndex(Key key) {
        int hashCode = key.hashCode();

        int startIndex = toIndex(hashCode);

        for(int i = startIndex; i < size; i++) {
            Key k = keys[i];
            if (k == null)
                return i - size;
            if (hashCode == k.hashCode() && key.equals(k)) {
                return i;
            }
        }

        for(int i = 0; i < startIndex; i++) {
            Key k = keys[i];
            if (k == null)
                return i - size;
            if (hashCode == k.hashCode() && key.equals(k)) {
                return i;
            }
        }

        throw new IllegalStateException("Could not find the key or a free sport...");
    }

    private void resize() {
        if (size < MAXIMUM_CAPACITY) {
            Key[] oldKeys = keys;
            Object[] oldValues = values;
            int oldSize = size;

            initSize(size << 1);

            for (int i = 0; i < oldSize; i++) {
                Key k = oldKeys[i];
                if (k != null) {
                    int ki = freeSpot(k);
                    keys[ki] = k;
                    values[ki] = oldValues[i];
                }
            }
        }
    }

    private int freeSpot(Key key) {
        int hashCode = key.hashCode();

        int startIndex = toIndex(hashCode);

        for(int i = startIndex; i < size; i++) {
            Key k = keys[i];
            if (k == null)
                return i;
        }

        for(int i = 0; i < startIndex; i++) {
            Key k = keys[i];
            if (k == null)
                return i;
        }

        throw new IllegalStateException("Could not find the key or a free sport...");
    }

    private void initSize(int newSize) {
        keys = new Key[newSize];
        values = new Object[newSize];
        mask = calculateMask(newSize);
        size = newSize;
        resizeThreshold = size >> 1;
    }

    private int toIndex(int hashCode) {
        return (hashCode & mask);
    }


    public void clear() {
        Arrays.fill(keys, null);
        Arrays.fill(values, null);
        nbValues = 0;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy