use of org.apache.ignite.internal.cache.query.index.sorted.IndexKeyDefinition in project ignite by apache.
the class InlineIndexTree method compare.
/**
* {@inheritDoc}
*/
@Override
protected int compare(BPlusIO<IndexRow> io, long pageAddr, int idx, IndexRow row) throws IgniteCheckedException {
if (inlineSize == 0) {
IndexRow currRow = getRow(io, pageAddr, idx);
int cmp = compareFullRows(currRow, row, 0);
return cmp == 0 ? mvccCompare(currRow, row) : cmp;
}
int fieldOff = 0;
// Use it when can't compare values (variable length, for example).
int keyIdx;
IndexRow currRow = null;
int off = io.offset(idx);
List<IndexKeyDefinition> keyDefs = rowHnd.indexKeyDefinitions();
List<InlineIndexKeyType> keyTypes = rowHandler().inlineIndexKeyTypes();
for (keyIdx = 0; keyIdx < keyTypes.size(); keyIdx++) {
try {
// possible keys for that comparison).
if (row.key(keyIdx) == null)
return 0;
// Other keys are not inlined. Should compare as rows.
if (keyIdx >= keyTypes.size())
break;
int maxSize = inlineSize - fieldOff;
InlineIndexKeyType keyType = keyTypes.get(keyIdx);
int cmp = def.rowComparator().compareKey(pageAddr, off + fieldOff, maxSize, row.key(keyIdx), keyType);
if (cmp == CANT_BE_COMPARE || cmp == COMPARE_UNSUPPORTED)
break;
else
fieldOff += keyType.inlineSize(pageAddr, off + fieldOff);
if (cmp != 0) {
IndexKeyDefinition keyDef = keyDefs.get(keyIdx);
return applySortOrder(cmp, keyDef.order().sortOrder());
}
} catch (Exception e) {
throw new IgniteException("Failed to store new index row.", e);
}
}
if (keyIdx < keyDefs.size()) {
recommender.recommend(row, inlineSize);
if (currRow == null)
currRow = getRow(io, pageAddr, idx);
int ret = compareFullRows(currRow, row, keyIdx);
if (ret != 0)
return ret;
}
return mvccCompare((MvccIO) io, pageAddr, idx, row);
}
use of org.apache.ignite.internal.cache.query.index.sorted.IndexKeyDefinition in project ignite by apache.
the class InlineObjectBytesDetector method apply.
/**
* {@inheritDoc}
*/
@Override
public boolean apply(BPlusTree<IndexRow, IndexRow> tree, BPlusIO<IndexRow> io, long pageAddr, int idx) throws IgniteCheckedException {
IndexRow r = tree.getRow(io, pageAddr, idx);
int off = io.offset(idx);
int fieldOff = 0;
boolean varLenPresents = false;
IndexKeyTypeSettings keyTypeSettings = new IndexKeyTypeSettings();
Iterator<IndexKeyDefinition> it = keyDefs.iterator();
for (int i = 0; i < keyDefs.size(); ++i) {
IndexKeyDefinition keyDef = it.next();
if (fieldOff >= inlineSize)
return false;
if (keyDef.idxType() != IndexKeyTypes.JAVA_OBJECT) {
InlineIndexKeyType keyType = InlineIndexKeyTypeRegistry.get(keyDef.idxType(), keyTypeSettings);
if (keyType.inlineSize() < 0)
varLenPresents = true;
fieldOff += keyType.inlineSize(pageAddr, off + fieldOff);
continue;
}
IndexKey key = r.key(i);
if (key == NullIndexKey.INSTANCE)
return false;
int type = PageUtils.getByte(pageAddr, off + fieldOff);
// We can have garbage in memory and need to compare data.
if (type == IndexKeyTypes.JAVA_OBJECT) {
int len = PageUtils.getShort(pageAddr, off + fieldOff + 1);
len &= 0x7FFF;
byte[] originalObjBytes = ((JavaObjectIndexKey) key).bytesNoCopy();
// Read size more then available space or more then origin length.
if (len > inlineSize - fieldOff - 3 || len > originalObjBytes.length) {
inlineObjectSupportedDecision(false, "length is big " + len);
return true;
}
// Try compare byte by byte for fully or partial inlined object.
byte[] inlineBytes = PageUtils.getBytes(pageAddr, off + fieldOff + 3, len);
if (!Arrays.equals(inlineBytes, originalObjBytes)) {
inlineObjectSupportedDecision(false, "byte compare");
return true;
}
inlineObjectSupportedDecision(true, len + " bytes compared");
return true;
}
if (type == IndexKeyTypes.UNKNOWN && varLenPresents) {
// 2: short string, inlined java object
return false;
}
inlineObjectSupportedDecision(false, "inline type " + type);
return true;
}
inlineObjectSupportedDecision(true, "no java objects for inlining");
return true;
}
use of org.apache.ignite.internal.cache.query.index.sorted.IndexKeyDefinition in project ignite by apache.
the class QueryIndexKeyDefinitionProvider method keyDefinitions.
/**
* @return List of index key definitions.
*/
public LinkedHashMap<String, IndexKeyDefinition> keyDefinitions() {
if (keyDefs != null)
return keyDefs;
LinkedHashMap<String, IndexKeyDefinition> idxKeyDefinitions = new LinkedHashMap<>();
for (IndexColumn c : h2IdxColumns) idxKeyDefinitions.put(c.columnName, keyDefinition(c));
IndexColumn.mapColumns(h2IdxColumns.toArray(new IndexColumn[0]), table);
keyDefs = idxKeyDefinitions;
return keyDefs;
}
use of org.apache.ignite.internal.cache.query.index.sorted.IndexKeyDefinition in project ignite by apache.
the class GeoSpatialUtils method createIndex.
/**
*/
public static GridH2SpatialIndex createIndex(GridH2Table tbl, String idxName, List<IndexColumn> cols) {
try {
IndexName name = new IndexName(tbl.cacheName(), tbl.getSchema().getName(), tbl.getName(), idxName);
LinkedHashMap<String, IndexKeyDefinition> keyDefs = new QueryIndexKeyDefinitionProvider(tbl, cols).keyDefinitions();
List<InlineIndexKeyType> idxKeyTypes = InlineIndexKeyTypeRegistry.types(keyDefs.values(), DUMMY_SETTINGS);
QueryIndexRowHandler rowHnd = new QueryIndexRowHandler(tbl, cols, keyDefs, idxKeyTypes, DUMMY_SETTINGS);
final int segments = tbl.rowDescriptor().cacheInfo().config().getQueryParallelism();
IndexDefinition def = new GeoSpatialIndexDefinition(name, keyDefs, rowHnd, segments);
Index idx = tbl.cacheContext().kernalContext().indexProcessor().createIndex(tbl.cacheContext(), GeoSpatialIndexFactory.INSTANCE, def);
return new GridH2SpatialIndex(idx.unwrap(GeoSpatialIndexImpl.class));
} catch (Exception e) {
throw new IgniteException("Failed to instantiate", e);
}
}
use of org.apache.ignite.internal.cache.query.index.sorted.IndexKeyDefinition in project ignite by apache.
the class IndexQueryProcessor method mergeIndexQueryCriteria.
/**
* Merges multiple criteria for the same field into single criterion.
*/
private Map<String, RangeIndexQueryCriterion> mergeIndexQueryCriteria(InlineIndexImpl idx, SortedIndexDefinition idxDef, IndexQueryDesc idxQryDesc) throws IgniteCheckedException {
Map<String, RangeIndexQueryCriterion> mergedCriteria = new HashMap<>();
Map<String, IndexKeyDefinition> idxFlds = idxDef.indexKeyDefinitions();
IndexKeyTypeSettings keyTypeSettings = idx.segment(0).rowHandler().indexKeyTypeSettings();
CacheObjectContext coctx = idx.segment(0).cacheGroupContext().cacheObjectContext();
IndexRowComparator keyCmp = idxDef.rowComparator();
for (IndexQueryCriterion c : idxQryDesc.criteria()) {
RangeIndexQueryCriterion crit = (RangeIndexQueryCriterion) c;
String fldName = idxFlds.containsKey(crit.field()) ? crit.field() : QueryUtils.normalizeObjectName(crit.field(), false);
IndexKeyDefinition keyDef = idxFlds.get(fldName);
if (keyDef == null)
throw failIndexQuery("Index doesn't match criteria", idxDef, idxQryDesc);
IndexKey l = key(crit.lower(), crit.lowerNull(), keyDef, keyTypeSettings, coctx);
IndexKey u = key(crit.upper(), crit.upperNull(), keyDef, keyTypeSettings, coctx);
if (l != null && u != null && keyCmp.compareKey(l, u) > 0) {
throw failIndexQuery("Illegal criterion: lower boundary is greater than the upper boundary: " + rangeDesc(crit, fldName, null, null), idxDef, idxQryDesc);
}
boolean lowIncl = crit.lowerIncl();
boolean upIncl = crit.upperIncl();
boolean lowNull = crit.lowerNull();
boolean upNull = crit.upperNull();
if (mergedCriteria.containsKey(fldName)) {
RangeIndexQueryCriterion prev = mergedCriteria.get(fldName);
IndexKey prevLower = (IndexKey) prev.lower();
IndexKey prevUpper = (IndexKey) prev.upper();
// Validate merged criteria.
if (!checkBoundaries(l, prevUpper, crit.lowerIncl(), prev.upperIncl(), keyCmp) || !checkBoundaries(prevLower, u, prev.lowerIncl(), crit.upperIncl(), keyCmp)) {
String prevDesc = rangeDesc(prev, null, prevLower == null ? null : prevLower.key(), prevUpper == null ? null : prevUpper.key());
throw failIndexQuery("Failed to merge criterion " + rangeDesc(crit, fldName, null, null) + " with previous criteria range " + prevDesc, idxDef, idxQryDesc);
}
int lowCmp = 0;
// Use previous lower boudary, as it's greater than the current.
if (l == null || (prevLower != null && (lowCmp = keyCmp.compareKey(prevLower, l)) >= 0)) {
l = prevLower;
lowIncl = lowCmp != 0 ? prev.lowerIncl() : prev.lowerIncl() ? lowIncl : prev.lowerIncl();
lowNull = prev.lowerNull();
}
int upCmp = 0;
// Use previous upper boudary, as it's less than the current.
if (u == null || (prevUpper != null && (upCmp = keyCmp.compareKey(prevUpper, u)) <= 0)) {
u = prevUpper;
upIncl = upCmp != 0 ? prev.upperIncl() : prev.upperIncl() ? upIncl : prev.upperIncl();
upNull = prev.upperNull();
}
}
RangeIndexQueryCriterion idxKeyCrit = new RangeIndexQueryCriterion(fldName, l, u);
idxKeyCrit.lowerIncl(lowIncl);
idxKeyCrit.upperIncl(upIncl);
idxKeyCrit.lowerNull(lowNull);
idxKeyCrit.upperNull(upNull);
mergedCriteria.put(fldName, idxKeyCrit);
}
return mergedCriteria;
}
Aggregations