use of org.apache.ignite.internal.cache.query.index.sorted.IndexKeyTypeSettings 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.IndexKeyTypeSettings in project ignite by apache.
the class InlineIndexColumnTest method putAndCompare.
/**
* @param v1 Value 1.
* @param v2 Value 2.
* @param maxSize Max inline size.
* @return Compare result.
* @throws Exception If failed.
*/
private <T> int putAndCompare(T v1, T v2, Class<T> cls, int maxSize) throws Exception {
DataRegionConfiguration plcCfg = new DataRegionConfiguration().setInitialSize(1024 * MB).setMaxSize(1024 * MB);
DataRegionMetricsImpl dataRegionMetrics = new DataRegionMetricsImpl(plcCfg, new GridTestKernalContext(log()));
PageMemory pageMem = new PageMemoryNoStoreImpl(log, new UnsafeMemoryProvider(log), null, PAGE_SIZE, plcCfg, dataRegionMetrics, false);
pageMem.start();
long pageId = 0L;
long page = 0L;
try {
pageId = pageMem.allocatePage(CACHE_ID, 1, PageIdAllocator.FLAG_DATA);
page = pageMem.acquirePage(CACHE_ID, pageId);
long pageAddr = pageMem.readLock(CACHE_ID, pageId, page);
int off = 0;
IndexKeyTypeSettings keyTypeSettings = new IndexKeyTypeSettings().inlineObjHash(inlineObjHash).stringOptimizedCompare(true);
InlineIndexKeyType keyType = InlineIndexKeyTypeRegistry.get(wrap(v1, cls).getType(), keyTypeSettings);
keyType.put(pageAddr, off, idxKey(wrap(v1, cls)), maxSize);
return keyType.compare(pageAddr, off, maxSize, idxKey(wrap(v2, cls)));
} finally {
if (page != 0L)
pageMem.releasePage(CACHE_ID, pageId, page);
pageMem.stop(true);
}
}
use of org.apache.ignite.internal.cache.query.index.sorted.IndexKeyTypeSettings in project ignite by apache.
the class InlineIndexColumnTest method testPutGet.
/**
*/
private void testPutGet(Value v1, Value v2, Value v3) throws Exception {
DataRegionConfiguration plcCfg = new DataRegionConfiguration().setInitialSize(1024 * MB).setMaxSize(1024 * MB);
PageMemory pageMem = new PageMemoryNoStoreImpl(log, new UnsafeMemoryProvider(log), null, PAGE_SIZE, plcCfg, new DataRegionMetricsImpl(plcCfg, new GridTestKernalContext(log())), false);
pageMem.start();
long pageId = 0L;
long page = 0L;
try {
pageId = pageMem.allocatePage(CACHE_ID, 1, PageIdAllocator.FLAG_DATA);
page = pageMem.acquirePage(CACHE_ID, pageId);
long pageAddr = pageMem.readLock(CACHE_ID, pageId, page);
int off = 0;
int max = 255;
IndexKeyTypeSettings keyTypeSettings = new IndexKeyTypeSettings().inlineObjHash(false).stringOptimizedCompare(false);
InlineIndexKeyType keyType = InlineIndexKeyTypeRegistry.get(v1.getType(), keyTypeSettings);
off += keyType.put(pageAddr, off, idxKey(v1), max - off);
off += keyType.put(pageAddr, off, idxKey(v2), max - off);
off += keyType.put(pageAddr, off, idxKey(v3), max - off);
IndexKey v11 = keyType.get(pageAddr, 0, max);
IndexKey v22 = keyType.get(pageAddr, keyType.inlineSize(pageAddr, 0), max);
assertEquals(v1.getObject(), v11.key());
assertEquals(v2.getObject(), v22.key());
assertEquals(0, keyType.compare(pageAddr, 0, max, idxKey(v1)));
} finally {
if (page != 0L)
pageMem.releasePage(CACHE_ID, pageId, page);
pageMem.stop(true);
}
}
use of org.apache.ignite.internal.cache.query.index.sorted.IndexKeyTypeSettings in project ignite by apache.
the class InlineIndexColumnTest method testBytes.
/**
*/
@Test
public void testBytes() throws Exception {
DataRegionConfiguration plcCfg = new DataRegionConfiguration().setInitialSize(1024 * MB).setMaxSize(1024 * MB);
PageMemory pageMem = new PageMemoryNoStoreImpl(log, new UnsafeMemoryProvider(log), null, PAGE_SIZE, plcCfg, new DataRegionMetricsImpl(plcCfg, new GridTestKernalContext(log())), false);
pageMem.start();
long pageId = 0L;
long page = 0L;
try {
pageId = pageMem.allocatePage(CACHE_ID, 1, PageIdAllocator.FLAG_DATA);
page = pageMem.acquirePage(CACHE_ID, pageId);
long pageAddr = pageMem.readLock(CACHE_ID, pageId, page);
int off = 0;
IndexKeyTypeSettings keyTypeSettings = new IndexKeyTypeSettings().inlineObjHash(false).stringOptimizedCompare(false);
InlineIndexKeyType keyType = InlineIndexKeyTypeRegistry.get(Value.BYTES, keyTypeSettings);
int maxSize = 3 + 3;
int savedBytesCnt = keyType.put(pageAddr, off, idxKey(ValueBytes.get(new byte[] { 1, 2, 3, 4, 5 }), keyTypeSettings), maxSize);
assertTrue(savedBytesCnt > 0);
assertTrue(savedBytesCnt <= maxSize);
maxSize = 3 + 5;
assertTrue(Arrays.equals(new byte[] { 1, 2, 3 }, (byte[]) keyType.get(pageAddr, off, maxSize).key()));
savedBytesCnt = keyType.put(pageAddr, off, idxKey(ValueBytes.get(new byte[] { 1, 2, 3, 4, 5 }), keyTypeSettings), maxSize);
assertTrue(savedBytesCnt > 0);
assertTrue(savedBytesCnt <= maxSize);
assertTrue(Arrays.equals(new byte[] { 1, 2, 3, 4, 5 }, (byte[]) keyType.get(pageAddr, off, maxSize).key()));
} finally {
if (page != 0L)
pageMem.releasePage(CACHE_ID, pageId, page);
pageMem.stop(true);
}
}
use of org.apache.ignite.internal.cache.query.index.sorted.IndexKeyTypeSettings 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