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

com.hazelcast.query.impl.UnsortedIndexStore Maven / Gradle / Ivy

There is a newer version: 5.5.0
Show newest version
/*
 * Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
 *
 * 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 com.hazelcast.query.impl;

import com.hazelcast.nio.serialization.Data;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Store indexes out of turn.
 */
public class UnsortedIndexStore extends BaseIndexStore {

    private final ConcurrentMap recordsWithNullValue
            = new ConcurrentHashMap();

    private final ConcurrentMap> recordMap
            = new ConcurrentHashMap>(1000);

    @Override
    void newIndexInternal(Comparable newValue, QueryableEntry record) {
        if (newValue instanceof IndexImpl.NullObject) {
            recordsWithNullValue.put(record.getKeyData(), record);
        } else {
            mapAttributeToEntry(newValue, record);
        }
    }

    private void mapAttributeToEntry(Comparable attribute, QueryableEntry entry) {
        ConcurrentMap records = recordMap.get(attribute);
        if (records == null) {
            records = new ConcurrentHashMap(1, LOAD_FACTOR, 1);
            recordMap.put(attribute, records);
        }
        records.put(entry.getKeyData(), entry);
    }

    @Override
    void removeIndexInternal(Comparable oldValue, Data indexKey) {
        if (oldValue instanceof IndexImpl.NullObject) {
            recordsWithNullValue.remove(indexKey);
        } else {
            removeMappingForAttribute(oldValue, indexKey);
        }
    }

    private void removeMappingForAttribute(Object attribute, Data indexKey) {
        ConcurrentMap records = recordMap.get(attribute);
        if (records != null) {
            records.remove(indexKey);
            if (records.size() == 0) {
                recordMap.remove(attribute);
            }
        }
    }

    @Override
    public void clear() {
        takeWriteLock();
        try {
            recordsWithNullValue.clear();
            recordMap.clear();
        } finally {
            releaseWriteLock();
        }
    }

    @Override
    public Set getSubRecordsBetween(Comparable from, Comparable to) {
        takeReadLock();
        try {
            MultiResultSet results = createMultiResultSet();
            Comparable paramFrom = from;
            Comparable paramTo = to;
            int trend = paramFrom.compareTo(paramTo);
            if (trend == 0) {
                ConcurrentMap records = recordMap.get(paramFrom);
                if (records != null) {
                    copyToMultiResultSet(results, records);
                }
                return results;
            }
            if (trend < 0) {
                Comparable oldFrom = paramFrom;
                paramFrom = to;
                paramTo = oldFrom;
            }
            for (Map.Entry> recordMapEntry : recordMap.entrySet()) {
                Comparable value = recordMapEntry.getKey();
                if (value.compareTo(paramFrom) <= 0 && value.compareTo(paramTo) >= 0) {
                    ConcurrentMap records = recordMapEntry.getValue();
                    if (records != null) {
                        copyToMultiResultSet(results, records);
                    }
                }
            }
            return results;
        } finally {
            releaseReadLock();
        }
    }

    @Override
    public Set getSubRecords(ComparisonType comparisonType, Comparable searchedValue) {
        takeReadLock();
        try {
            MultiResultSet results = createMultiResultSet();
            for (Map.Entry> recordMapEntry : recordMap.entrySet()) {
                Comparable value = recordMapEntry.getKey();
                boolean valid;
                int result = searchedValue.compareTo(value);
                switch (comparisonType) {
                    case LESSER:
                        valid = result > 0;
                        break;
                    case LESSER_EQUAL:
                        valid = result >= 0;
                        break;
                    case GREATER:
                        valid = result < 0;
                        break;
                    case GREATER_EQUAL:
                        valid = result <= 0;
                        break;
                    case NOT_EQUAL:
                        valid = result != 0;
                        break;
                    default:
                        throw new IllegalStateException("Unrecognized comparisonType: " + comparisonType);
                }
                if (valid) {
                    ConcurrentMap records = recordMapEntry.getValue();
                    if (records != null) {
                        copyToMultiResultSet(results, records);
                    }
                }
            }
            return results;
        } finally {
            releaseReadLock();
        }
    }

    @Override
    public Set getRecords(Comparable value) {
        takeReadLock();
        try {
            if (value instanceof IndexImpl.NullObject) {
                return toSingleResultSet(recordsWithNullValue);
            } else {
                return toSingleResultSet(recordMap.get(value));
            }
        } finally {
            releaseReadLock();
        }
    }

    @Override
    public Set getRecords(Set values) {
        takeReadLock();
        try {
            MultiResultSet results = createMultiResultSet();
            for (Comparable value : values) {
                ConcurrentMap records;
                if (value instanceof IndexImpl.NullObject) {
                    records = recordsWithNullValue;
                } else {
                    records = recordMap.get(value);
                }
                if (records != null) {
                    copyToMultiResultSet(results, records);
                }
            }
            return results;
        } finally {
            releaseReadLock();
        }
    }

    @Override
    public String toString() {
        return "UnsortedIndexStore{"
                + "recordMap=" + recordMap.size()
                + '}';
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy