Merge branch 'master' into ccr
* master: TEST: testDocStats should always use forceMerge (#32450) TEST: Avoid deletion in FlushIT AwaitsFix IndexShardTests#testDocStats Painless: Add method type to method. (#32441)
This commit is contained in:
commit
d2a88f5c62
|
@ -93,12 +93,12 @@ public class FunctionRef {
|
||||||
* @param numCaptures number of captured arguments
|
* @param numCaptures number of captured arguments
|
||||||
*/
|
*/
|
||||||
public FunctionRef(Class<?> expected, PainlessMethod interfaceMethod, PainlessMethod delegateMethod, int numCaptures) {
|
public FunctionRef(Class<?> expected, PainlessMethod interfaceMethod, PainlessMethod delegateMethod, int numCaptures) {
|
||||||
MethodType delegateMethodType = delegateMethod.getMethodType();
|
MethodType delegateMethodType = delegateMethod.methodType;
|
||||||
|
|
||||||
interfaceMethodName = interfaceMethod.name;
|
interfaceMethodName = interfaceMethod.name;
|
||||||
factoryMethodType = MethodType.methodType(expected,
|
factoryMethodType = MethodType.methodType(expected,
|
||||||
delegateMethodType.dropParameterTypes(numCaptures, delegateMethodType.parameterCount()));
|
delegateMethodType.dropParameterTypes(numCaptures, delegateMethodType.parameterCount()));
|
||||||
interfaceMethodType = interfaceMethod.getMethodType().dropParameterTypes(0, 1);
|
interfaceMethodType = interfaceMethod.methodType.dropParameterTypes(0, 1);
|
||||||
|
|
||||||
// the Painless$Script class can be inferred if owner is null
|
// the Painless$Script class can be inferred if owner is null
|
||||||
if (delegateMethod.target == null) {
|
if (delegateMethod.target == null) {
|
||||||
|
@ -142,7 +142,7 @@ public class FunctionRef {
|
||||||
interfaceMethodName = interfaceMethod.name;
|
interfaceMethodName = interfaceMethod.name;
|
||||||
factoryMethodType = MethodType.methodType(expected,
|
factoryMethodType = MethodType.methodType(expected,
|
||||||
delegateMethodType.dropParameterTypes(numCaptures, delegateMethodType.parameterCount()));
|
delegateMethodType.dropParameterTypes(numCaptures, delegateMethodType.parameterCount()));
|
||||||
interfaceMethodType = interfaceMethod.getMethodType().dropParameterTypes(0, 1);
|
interfaceMethodType = interfaceMethod.methodType.dropParameterTypes(0, 1);
|
||||||
|
|
||||||
delegateClassName = CLASS_NAME;
|
delegateClassName = CLASS_NAME;
|
||||||
delegateInvokeType = H_INVOKESTATIC;
|
delegateInvokeType = H_INVOKESTATIC;
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.elasticsearch.painless.spi.WhitelistMethod;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
@ -356,10 +357,12 @@ public class PainlessLookupBuilder {
|
||||||
"[[" + targetCanonicalClassName + "], " + typesToCanonicalTypeNames(typeParameters) + "] not found", iae);
|
"[[" + targetCanonicalClassName + "], " + typesToCanonicalTypeNames(typeParameters) + "] not found", iae);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MethodType methodType = methodHandle.type();
|
||||||
|
|
||||||
painlessConstructor = painlessMethodCache.computeIfAbsent(
|
painlessConstructor = painlessMethodCache.computeIfAbsent(
|
||||||
new PainlessMethodCacheKey(targetClass, CONSTRUCTOR_NAME, typeParameters),
|
new PainlessMethodCacheKey(targetClass, CONSTRUCTOR_NAME, typeParameters),
|
||||||
key -> new PainlessMethod(CONSTRUCTOR_NAME, targetClass, null, void.class, typeParameters,
|
key -> new PainlessMethod(CONSTRUCTOR_NAME, targetClass, null, void.class, typeParameters,
|
||||||
asmConstructor, javaConstructor.getModifiers(), methodHandle)
|
asmConstructor, javaConstructor.getModifiers(), methodHandle, methodType)
|
||||||
);
|
);
|
||||||
|
|
||||||
painlessClassBuilder.constructors.put(painlessMethodKey, painlessConstructor);
|
painlessClassBuilder.constructors.put(painlessMethodKey, painlessConstructor);
|
||||||
|
@ -516,10 +519,12 @@ public class PainlessLookupBuilder {
|
||||||
"[" + methodName + "], " + typesToCanonicalTypeNames(typeParameters) + "] not found", iae);
|
"[" + methodName + "], " + typesToCanonicalTypeNames(typeParameters) + "] not found", iae);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MethodType methodType = methodHandle.type();
|
||||||
|
|
||||||
painlessMethod = painlessMethodCache.computeIfAbsent(
|
painlessMethod = painlessMethodCache.computeIfAbsent(
|
||||||
new PainlessMethodCacheKey(targetClass, methodName, typeParameters),
|
new PainlessMethodCacheKey(targetClass, methodName, typeParameters),
|
||||||
key -> new PainlessMethod(methodName, targetClass, null, returnType,
|
key -> new PainlessMethod(methodName, targetClass, null, returnType,
|
||||||
typeParameters, asmMethod, javaMethod.getModifiers(), methodHandle));
|
typeParameters, asmMethod, javaMethod.getModifiers(), methodHandle, methodType));
|
||||||
|
|
||||||
painlessClassBuilder.staticMethods.put(painlessMethodKey, painlessMethod);
|
painlessClassBuilder.staticMethods.put(painlessMethodKey, painlessMethod);
|
||||||
} else if ((painlessMethod.name.equals(methodName) && painlessMethod.rtn == returnType &&
|
} else if ((painlessMethod.name.equals(methodName) && painlessMethod.rtn == returnType &&
|
||||||
|
@ -557,10 +562,12 @@ public class PainlessLookupBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MethodType methodType = methodHandle.type();
|
||||||
|
|
||||||
painlessMethod = painlessMethodCache.computeIfAbsent(
|
painlessMethod = painlessMethodCache.computeIfAbsent(
|
||||||
new PainlessMethodCacheKey(targetClass, methodName, typeParameters),
|
new PainlessMethodCacheKey(targetClass, methodName, typeParameters),
|
||||||
key -> new PainlessMethod(methodName, targetClass, augmentedClass, returnType,
|
key -> new PainlessMethod(methodName, targetClass, augmentedClass, returnType,
|
||||||
typeParameters, asmMethod, javaMethod.getModifiers(), methodHandle));
|
typeParameters, asmMethod, javaMethod.getModifiers(), methodHandle, methodType));
|
||||||
|
|
||||||
painlessClassBuilder.methods.put(painlessMethodKey, painlessMethod);
|
painlessClassBuilder.methods.put(painlessMethodKey, painlessMethod);
|
||||||
} else if ((painlessMethod.name.equals(methodName) && painlessMethod.rtn == returnType &&
|
} else if ((painlessMethod.name.equals(methodName) && painlessMethod.rtn == returnType &&
|
||||||
|
|
|
@ -38,9 +38,10 @@ public class PainlessMethod {
|
||||||
public final org.objectweb.asm.commons.Method method;
|
public final org.objectweb.asm.commons.Method method;
|
||||||
public final int modifiers;
|
public final int modifiers;
|
||||||
public final MethodHandle handle;
|
public final MethodHandle handle;
|
||||||
|
public final MethodType methodType;
|
||||||
|
|
||||||
public PainlessMethod(String name, Class<?> target, Class<?> augmentation, Class<?> rtn, List<Class<?>> arguments,
|
public PainlessMethod(String name, Class<?> target, Class<?> augmentation, Class<?> rtn, List<Class<?>> arguments,
|
||||||
org.objectweb.asm.commons.Method method, int modifiers, MethodHandle handle) {
|
org.objectweb.asm.commons.Method method, int modifiers, MethodHandle handle, MethodType methodType) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.augmentation = augmentation;
|
this.augmentation = augmentation;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
|
@ -49,54 +50,7 @@ public class PainlessMethod {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.modifiers = modifiers;
|
this.modifiers = modifiers;
|
||||||
this.handle = handle;
|
this.handle = handle;
|
||||||
}
|
this.methodType = methodType;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns MethodType for this method.
|
|
||||||
* <p>
|
|
||||||
* This works even for user-defined Methods (where the MethodHandle is null).
|
|
||||||
*/
|
|
||||||
public MethodType getMethodType() {
|
|
||||||
// we have a methodhandle already (e.g. whitelisted class)
|
|
||||||
// just return its type
|
|
||||||
if (handle != null) {
|
|
||||||
return handle.type();
|
|
||||||
}
|
|
||||||
// otherwise compute it
|
|
||||||
final Class<?> params[];
|
|
||||||
final Class<?> returnValue;
|
|
||||||
if (augmentation != null) {
|
|
||||||
// static method disguised as virtual/interface method
|
|
||||||
params = new Class<?>[1 + arguments.size()];
|
|
||||||
params[0] = augmentation;
|
|
||||||
for (int i = 0; i < arguments.size(); i++) {
|
|
||||||
params[i + 1] = PainlessLookupUtility.typeToJavaType(arguments.get(i));
|
|
||||||
}
|
|
||||||
returnValue = PainlessLookupUtility.typeToJavaType(rtn);
|
|
||||||
} else if (Modifier.isStatic(modifiers)) {
|
|
||||||
// static method: straightforward copy
|
|
||||||
params = new Class<?>[arguments.size()];
|
|
||||||
for (int i = 0; i < arguments.size(); i++) {
|
|
||||||
params[i] = PainlessLookupUtility.typeToJavaType(arguments.get(i));
|
|
||||||
}
|
|
||||||
returnValue = PainlessLookupUtility.typeToJavaType(rtn);
|
|
||||||
} else if ("<init>".equals(name)) {
|
|
||||||
// constructor: returns the owner class
|
|
||||||
params = new Class<?>[arguments.size()];
|
|
||||||
for (int i = 0; i < arguments.size(); i++) {
|
|
||||||
params[i] = PainlessLookupUtility.typeToJavaType(arguments.get(i));
|
|
||||||
}
|
|
||||||
returnValue = target;
|
|
||||||
} else {
|
|
||||||
// virtual/interface method: add receiver class
|
|
||||||
params = new Class<?>[1 + arguments.size()];
|
|
||||||
params[0] = target;
|
|
||||||
for (int i = 0; i < arguments.size(); i++) {
|
|
||||||
params[i + 1] = PainlessLookupUtility.typeToJavaType(arguments.get(i));
|
|
||||||
}
|
|
||||||
returnValue = PainlessLookupUtility.typeToJavaType(rtn);
|
|
||||||
}
|
|
||||||
return MethodType.methodType(returnValue, params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(MethodWriter writer) {
|
public void write(MethodWriter writer) {
|
||||||
|
@ -118,7 +72,7 @@ public class PainlessMethod {
|
||||||
// method since java 8 did not check, but java 9 and 10 do
|
// method since java 8 did not check, but java 9 and 10 do
|
||||||
if (Modifier.isInterface(clazz.getModifiers())) {
|
if (Modifier.isInterface(clazz.getModifiers())) {
|
||||||
writer.visitMethodInsn(Opcodes.INVOKESTATIC,
|
writer.visitMethodInsn(Opcodes.INVOKESTATIC,
|
||||||
type.getInternalName(), name, getMethodType().toMethodDescriptorString(), true);
|
type.getInternalName(), name, methodType.toMethodDescriptorString(), true);
|
||||||
} else {
|
} else {
|
||||||
writer.invokeStatic(type, method);
|
writer.invokeStatic(type, method);
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,9 +145,11 @@ public final class SFunction extends AStatement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int modifiers = Modifier.STATIC | Modifier.PRIVATE;
|
||||||
org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(name, MethodType.methodType(
|
org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(name, MethodType.methodType(
|
||||||
PainlessLookupUtility.typeToJavaType(rtnType), paramClasses).toMethodDescriptorString());
|
PainlessLookupUtility.typeToJavaType(rtnType), paramClasses).toMethodDescriptorString());
|
||||||
this.method = new PainlessMethod(name, null, null, rtnType, paramTypes, method, Modifier.STATIC | Modifier.PRIVATE, null);
|
MethodType methodType = MethodType.methodType(PainlessLookupUtility.typeToJavaType(rtnType), paramClasses);
|
||||||
|
this.method = new PainlessMethod(name, null, null, rtnType, paramTypes, method, modifiers, null, methodType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2392,9 +2392,7 @@ public class IndexShardTests extends IndexShardTestCase {
|
||||||
indexShard = newStartedShard(
|
indexShard = newStartedShard(
|
||||||
Settings.builder().put(IndexSettings.INDEX_SOFT_DELETES_RETENTION_OPERATIONS_SETTING.getKey(), 0).build());
|
Settings.builder().put(IndexSettings.INDEX_SOFT_DELETES_RETENTION_OPERATIONS_SETTING.getKey(), 0).build());
|
||||||
final long numDocs = randomIntBetween(2, 32); // at least two documents so we have docs to delete
|
final long numDocs = randomIntBetween(2, 32); // at least two documents so we have docs to delete
|
||||||
// Delete at least numDocs/10 documents otherwise the number of deleted docs will be below 10%
|
final long numDocsToDelete = randomLongBetween(1, numDocs);
|
||||||
// and forceMerge will refuse to expunge deletes
|
|
||||||
final long numDocsToDelete = randomIntBetween((int) Math.ceil(Math.nextUp(numDocs / 10.0)), Math.toIntExact(numDocs));
|
|
||||||
for (int i = 0; i < numDocs; i++) {
|
for (int i = 0; i < numDocs; i++) {
|
||||||
final String id = Integer.toString(i);
|
final String id = Integer.toString(i);
|
||||||
indexDoc(indexShard, "_doc", id);
|
indexDoc(indexShard, "_doc", id);
|
||||||
|
@ -2460,7 +2458,6 @@ public class IndexShardTests extends IndexShardTestCase {
|
||||||
|
|
||||||
// merge them away
|
// merge them away
|
||||||
final ForceMergeRequest forceMergeRequest = new ForceMergeRequest();
|
final ForceMergeRequest forceMergeRequest = new ForceMergeRequest();
|
||||||
forceMergeRequest.onlyExpungeDeletes(randomBoolean());
|
|
||||||
forceMergeRequest.maxNumSegments(1);
|
forceMergeRequest.maxNumSegments(1);
|
||||||
indexShard.forceMerge(forceMergeRequest);
|
indexShard.forceMerge(forceMergeRequest);
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,6 @@ public class FlushIT extends ESIntegTestCase {
|
||||||
assertThat(fullResult.successfulShards(), equalTo(numberOfReplicas + 1));
|
assertThat(fullResult.successfulShards(), equalTo(numberOfReplicas + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/32436")
|
|
||||||
public void testDoNotRenewSyncedFlushWhenAllSealed() throws Exception {
|
public void testDoNotRenewSyncedFlushWhenAllSealed() throws Exception {
|
||||||
internalCluster().ensureAtLeastNumDataNodes(between(2, 3));
|
internalCluster().ensureAtLeastNumDataNodes(between(2, 3));
|
||||||
final int numberOfReplicas = internalCluster().numDataNodes() - 1;
|
final int numberOfReplicas = internalCluster().numDataNodes() - 1;
|
||||||
|
@ -311,7 +310,7 @@ public class FlushIT extends ESIntegTestCase {
|
||||||
// Shards were updated, renew synced flush.
|
// Shards were updated, renew synced flush.
|
||||||
final int moreDocs = between(1, 10);
|
final int moreDocs = between(1, 10);
|
||||||
for (int i = 0; i < moreDocs; i++) {
|
for (int i = 0; i < moreDocs; i++) {
|
||||||
index("test", "doc", Integer.toString(i));
|
index("test", "doc", "more-" + i);
|
||||||
}
|
}
|
||||||
final ShardsSyncedFlushResult thirdSeal = SyncedFlushUtil.attemptSyncedFlush(logger, internalCluster(), shardId);
|
final ShardsSyncedFlushResult thirdSeal = SyncedFlushUtil.attemptSyncedFlush(logger, internalCluster(), shardId);
|
||||||
assertThat(thirdSeal.successfulShards(), equalTo(numberOfReplicas + 1));
|
assertThat(thirdSeal.successfulShards(), equalTo(numberOfReplicas + 1));
|
||||||
|
|
Loading…
Reference in New Issue