use of org.apache.ignite.internal.cache.query.index.sorted.keys.JavaObjectIndexKey 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.keys.JavaObjectIndexKey in project ignite by apache.
the class InlineIndexColumnTest method testJavaObjectInlineBytes.
/**
*/
@Test
public void testJavaObjectInlineBytes() 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(false).stringOptimizedCompare(false);
InlineIndexKeyType keyType = InlineIndexKeyTypeRegistry.get(Value.JAVA_OBJECT, keyTypeSettings);
ValueJavaObject exp = ValueJavaObject.getNoCopy(new TestPojo(4, 3L), null, null);
int maxSize = 3 + 3;
int savedBytesCnt = keyType.put(pageAddr, off, idxKey(exp), maxSize);
assertTrue(savedBytesCnt > 0);
assertTrue(savedBytesCnt <= maxSize);
maxSize = 3 + exp.getBytesNoCopy().length;
assertTrue(Arrays.equals(Arrays.copyOf(exp.getBytesNoCopy(), 3), ((JavaObjectIndexKey) keyType.get(pageAddr, off, maxSize)).bytesNoCopy()));
savedBytesCnt = keyType.put(pageAddr, off, idxKey(ValueJavaObject.getNoCopy(null, exp.getBytesNoCopy(), null)), maxSize);
assertTrue(savedBytesCnt > 0);
assertTrue(savedBytesCnt <= maxSize);
assertTrue(Arrays.equals(exp.getBytesNoCopy(), ((JavaObjectIndexKey) keyType.get(pageAddr, off, maxSize)).bytesNoCopy()));
} finally {
if (page != 0L)
pageMem.releasePage(CACHE_ID, pageId, page);
pageMem.stop(true);
}
}
Aggregations