
org.dizitart.no2.index.IndexMap Maven / Gradle / Ivy
/*
* Copyright (c) 2017-2021 Nitrite author or authors.
*
* 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 org.dizitart.no2.index;
import lombok.Getter;
import lombok.Setter;
import org.dizitart.no2.collection.NitriteId;
import org.dizitart.no2.common.DBNull;
import org.dizitart.no2.common.DBValue;
import org.dizitart.no2.common.tuples.Pair;
import org.dizitart.no2.store.NitriteMap;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author Anindya Chatterjee
* @since 4.0
*/
@SuppressWarnings("unchecked")
public class IndexMap {
private NitriteMap nitriteMap;
private NavigableMap navigableMap;
@Getter
@Setter
private boolean reverseScan;
/**
* Instantiates a new {@link IndexMap}.
*
* @param nitriteMap the nitrite map
*/
public IndexMap(NitriteMap nitriteMap) {
this.nitriteMap = nitriteMap;
}
/**
* Instantiates a new {@link IndexMap}.
*
* @param navigableMap the navigable map
*/
public IndexMap(NavigableMap navigableMap) {
this.navigableMap = navigableMap;
}
public > T firstKey() {
DBValue dbKey;
if (nitriteMap != null) {
dbKey = nitriteMap.firstKey();
} else if (navigableMap != null) {
dbKey = navigableMap.firstKey();
} else {
return null;
}
return dbKey == null || dbKey instanceof DBNull ? null : (T) dbKey.getValue();
}
public > T lastKey() {
DBValue dbKey;
if (nitriteMap != null) {
dbKey = nitriteMap.lastKey();
} else if (navigableMap != null) {
dbKey = navigableMap.lastKey();
} else {
return null;
}
return dbKey == null || dbKey instanceof DBNull ? null : (T) dbKey.getValue();
}
/**
* Get the largest key that is smaller than the given key, or null if no
* such key exists.
*
* @param the type parameter
* @param key the key
* @return the t
*/
public > T lowerKey(T key) {
DBValue dbKey = key == null ? DBNull.getInstance() : new DBValue(key);
if (nitriteMap != null) {
dbKey = nitriteMap.lowerKey(dbKey);
} else if (navigableMap != null) {
dbKey = navigableMap.lowerKey(dbKey);
}
return dbKey == null || dbKey instanceof DBNull ? null : (T) dbKey.getValue();
}
/**
* Get the smallest key that is larger than the given key, or null if no
* such key exists.
*
* @param the type parameter
* @param key the key
* @return the t
*/
public > T higherKey(T key) {
DBValue dbKey = key == null ? DBNull.getInstance() : new DBValue(key);
if (nitriteMap != null) {
dbKey = nitriteMap.higherKey(dbKey);
} else if (navigableMap != null) {
dbKey = navigableMap.higherKey(dbKey);
}
return dbKey == null || dbKey instanceof DBNull ? null : (T) dbKey.getValue();
}
/**
* Get the smallest key that is larger or equal to this key.
*
* @param the type parameter
* @param key the key
* @return the t
*/
public > T ceilingKey(T key) {
DBValue dbKey = key == null ? DBNull.getInstance() : new DBValue(key);
if (nitriteMap != null) {
dbKey = nitriteMap.ceilingKey(dbKey);
} else if (navigableMap != null) {
dbKey = navigableMap.ceilingKey(dbKey);
}
return dbKey == null || dbKey instanceof DBNull ? null : (T) dbKey.getValue();
}
/**
* Get the largest key that is smaller or equal to this key.
*
* @param the type parameter
* @param key the key
* @return the t
*/
public > T floorKey(T key) {
DBValue dbKey = key == null ? DBNull.getInstance() : new DBValue(key);
if (nitriteMap != null) {
dbKey = nitriteMap.floorKey(dbKey);
} else if (navigableMap != null) {
dbKey = navigableMap.floorKey(dbKey);
}
return dbKey == null || dbKey instanceof DBNull ? null : (T) dbKey.getValue();
}
/**
* Gets the value mapped with the specified key or null
otherwise.
*
* @param comparable the comparable
* @return the object
*/
public Object get(Comparable> comparable) {
DBValue dbKey = comparable == null ? DBNull.getInstance() : new DBValue(comparable);
if (nitriteMap != null) {
return nitriteMap.get(dbKey);
} else if (navigableMap != null) {
return navigableMap.get(dbKey);
}
return null;
}
/**
* Returns the iterable entries of the indexed items.
*
* @return the iterable
*/
public Iterable extends Pair, ?>> entries() {
if (nitriteMap != null) {
Iterator extends Pair> entryIterator;
if (!reverseScan) {
entryIterator = nitriteMap.entries().iterator();
} else {
entryIterator = nitriteMap.reversedEntries().iterator();
}
return (Iterable, ?>>) () -> new Iterator<>() {
@Override
public boolean hasNext() {
return entryIterator.hasNext();
}
@Override
public Pair, ?> next() {
Pair next = entryIterator.next();
DBValue dbKey = next.getFirst();
if (dbKey instanceof DBNull) {
return new Pair<>(null, next.getSecond());
} else {
return new Pair<>(dbKey.getValue(), next.getSecond());
}
}
};
} else if (navigableMap != null) {
Iterator extends Map.Entry> entryIterator;
if (reverseScan) {
entryIterator = navigableMap.descendingMap().entrySet().iterator();
} else {
entryIterator = navigableMap.entrySet().iterator();
}
return (Iterable, ?>>) () -> new Iterator, ?>>() {
@Override
public boolean hasNext() {
return entryIterator.hasNext();
}
@Override
public Pair, ?> next() {
Map.Entry next = entryIterator.next();
DBValue dbKey = next.getKey();
if (dbKey instanceof DBNull) {
return new Pair<>(null, next.getValue());
} else {
return new Pair<>(dbKey.getValue(), next.getValue());
}
}
};
}
return Collections.EMPTY_SET;
}
/**
* Gets the terminal nitrite ids from this map.
*
* @return the terminal nitrite ids
*/
public List getTerminalNitriteIds() {
List terminalResult = new CopyOnWriteArrayList<>();
// scan each entry of the navigable map and collect all terminal nitrite-ids
for (Pair, ?> entry : entries()) {
// if the value is terminal, collect all nitrite-ids
if (entry.getSecond() instanceof List) {
List nitriteIds = (List) entry.getSecond();
terminalResult.addAll(nitriteIds);
}
// if the value is not terminal, scan recursively
if (entry.getSecond() instanceof NavigableMap) {
NavigableMap subMap = (NavigableMap) entry.getSecond();
IndexMap indexMap = new IndexMap(subMap);
List nitriteIds = indexMap.getTerminalNitriteIds();
terminalResult.addAll(nitriteIds);
}
}
return terminalResult;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy