Skip to content

Commit

Permalink
# ignite-47 Store GridResourceField and GridResourceMethod to arrays …
Browse files Browse the repository at this point in the history
…instead of List (performance optimization)

(cherry picked from commit 1107e4b)
  • Loading branch information
sevdokimov-gg committed Mar 11, 2015
1 parent 2d1b861 commit 573b658
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 71 deletions.
Expand Up @@ -27,6 +27,9 @@
* Bean contains {@link Field} and {@link Annotation} for that class field. * Bean contains {@link Field} and {@link Annotation} for that class field.
*/ */
class GridResourceField { class GridResourceField {
/** */
static final GridResourceField[] EMPTY_ARRAY = new GridResourceField[0];

/** Field where resource should be injected. */ /** Field where resource should be injected. */
private final Field field; private final Field field;


Expand Down
Expand Up @@ -39,13 +39,11 @@ class GridResourceIoc {
new ConcurrentHashMap8<>(); new ConcurrentHashMap8<>();


/** Field cache. */ /** Field cache. */
private final ConcurrentMap<Class<?>, ConcurrentMap<Class<? extends Annotation>, private final ConcurrentMap<Class<?>, ConcurrentMap<Class<? extends Annotation>, GridResourceField[]>> fieldCache =
List<GridResourceField>>> fieldCache =
new ConcurrentHashMap8<>(); new ConcurrentHashMap8<>();


/** Method cache. */ /** Method cache. */
private final ConcurrentMap<Class<?>, ConcurrentMap<Class<? extends Annotation>, private final ConcurrentMap<Class<?>, ConcurrentMap<Class<? extends Annotation>, GridResourceMethod[]>> mtdCache =
List<GridResourceMethod>>> mtdCache =
new ConcurrentHashMap8<>(); new ConcurrentHashMap8<>();


/** /**
Expand Down Expand Up @@ -152,11 +150,9 @@ private boolean injectInternal(Object target,
return false; return false;


// Check if already inspected to avoid indefinite recursion. // Check if already inspected to avoid indefinite recursion.
if (checkedObjs.contains(target)) if (!checkedObjs.add(target))
return false; return false;


checkedObjs.add(target);

int annCnt = 0; int annCnt = 0;


boolean injected = false; boolean injected = false;
Expand Down Expand Up @@ -230,14 +226,14 @@ boolean isAnnotationPresent(Object target, Class<? extends Annotation> annCls, @
if (skipClss != null && skipClss.contains(targetCls)) if (skipClss != null && skipClss.contains(targetCls))
return false; return false;


List<GridResourceField> fields = getFieldsWithAnnotation(dep, targetCls, annCls); GridResourceField[] fields = getFieldsWithAnnotation(dep, targetCls, annCls);


if (!fields.isEmpty()) if (fields.length > 0)
return true; return true;


List<GridResourceMethod> mtds = getMethodsWithAnnotation(dep, targetCls, annCls); GridResourceMethod[] mtds = getMethodsWithAnnotation(dep, targetCls, annCls);


if (mtds.isEmpty()) { if (mtds.length == 0) {
if (skipClss == null) if (skipClss == null)
skipClss = F.addIfAbsent(skipCache, annCls, F.<Class<?>>newCSet()); skipClss = F.addIfAbsent(skipCache, annCls, F.<Class<?>>newCSet());


Expand Down Expand Up @@ -323,22 +319,27 @@ boolean isCached(String clsName) {
* @param annCls Annotation. * @param annCls Annotation.
* @return Set of methods with given annotations. * @return Set of methods with given annotations.
*/ */
List<GridResourceMethod> getMethodsWithAnnotation(@Nullable GridDeployment dep, Class<?> cls, GridResourceMethod[] getMethodsWithAnnotation(@Nullable GridDeployment dep, Class<?> cls,
Class<? extends Annotation> annCls) { Class<? extends Annotation> annCls) {
List<GridResourceMethod> mtds = getMethodsFromCache(cls, annCls); GridResourceMethod[] mtds = getMethodsFromCache(cls, annCls);


if (mtds == null) { if (mtds == null) {
mtds = new ArrayList<>(); List<GridResourceMethod> mtdsList = new ArrayList<>();


for (Class cls0 = cls; !cls0.equals(Object.class); cls0 = cls0.getSuperclass()) { for (Class cls0 = cls; !cls0.equals(Object.class); cls0 = cls0.getSuperclass()) {
for (Method mtd : cls0.getDeclaredMethods()) { for (Method mtd : cls0.getDeclaredMethods()) {
Annotation ann = mtd.getAnnotation(annCls); Annotation ann = mtd.getAnnotation(annCls);


if (ann != null) if (ann != null)
mtds.add(new GridResourceMethod(mtd, ann)); mtdsList.add(new GridResourceMethod(mtd, ann));
} }
} }


if (mtdsList.isEmpty())
mtds = GridResourceMethod.EMPTY_ARRAY;
else
mtds = mtdsList.toArray(new GridResourceMethod[mtdsList.size()]);

cacheMethods(dep, cls, annCls, mtds); cacheMethods(dep, cls, annCls, mtds);
} }


Expand All @@ -354,23 +355,28 @@ List<GridResourceMethod> getMethodsWithAnnotation(@Nullable GridDeployment dep,
* @param annCls Annotation. * @param annCls Annotation.
* @return Set of entries with given annotations. * @return Set of entries with given annotations.
*/ */
private List<GridResourceField> getFieldsWithAnnotation(@Nullable GridDeployment dep, Class<?> cls, private GridResourceField[] getFieldsWithAnnotation(@Nullable GridDeployment dep, Class<?> cls,
Class<? extends Annotation> annCls) { Class<? extends Annotation> annCls) {
List<GridResourceField> fields = getFieldsFromCache(cls, annCls); GridResourceField[] fields = getFieldsFromCache(cls, annCls);


if (fields == null) { if (fields == null) {
fields = new ArrayList<>(); List<GridResourceField> fieldsList = new ArrayList<>();


for (Class cls0 = cls; !cls0.equals(Object.class); cls0 = cls0.getSuperclass()) { for (Class cls0 = cls; !cls0.equals(Object.class); cls0 = cls0.getSuperclass()) {
for (Field field : cls0.getDeclaredFields()) { for (Field field : cls0.getDeclaredFields()) {
Annotation ann = field.getAnnotation(annCls); Annotation ann = field.getAnnotation(annCls);


if (ann != null || GridResourceUtils.mayRequireResources(field)) if (ann != null || GridResourceUtils.mayRequireResources(field))
// Account for anonymous inner classes. // Account for anonymous inner classes.
fields.add(new GridResourceField(field, ann)); fieldsList.add(new GridResourceField(field, ann));
} }
} }


if (fieldsList.isEmpty())
fields = GridResourceField.EMPTY_ARRAY;
else
fields = fieldsList.toArray(new GridResourceField[fieldsList.size()]);

cacheFields(dep, cls, annCls, fields); cacheFields(dep, cls, annCls, fields);
} }


Expand All @@ -384,8 +390,8 @@ private List<GridResourceField> getFieldsWithAnnotation(@Nullable GridDeployment
* @param annCls Annotation class for fields. * @param annCls Annotation class for fields.
* @return List of fields with given annotation, possibly {@code null}. * @return List of fields with given annotation, possibly {@code null}.
*/ */
@Nullable private List<GridResourceField> getFieldsFromCache(Class<?> cls, Class<? extends Annotation> annCls) { @Nullable private GridResourceField[] getFieldsFromCache(Class<?> cls, Class<? extends Annotation> annCls) {
Map<Class<? extends Annotation>, List<GridResourceField>> annCache = fieldCache.get(cls); Map<Class<? extends Annotation>, GridResourceField[]> annCache = fieldCache.get(cls);


return annCache != null ? annCache.get(annCls) : null; return annCache != null ? annCache.get(annCls) : null;
} }
Expand All @@ -399,7 +405,7 @@ private List<GridResourceField> getFieldsWithAnnotation(@Nullable GridDeployment
* @param fields Fields to cache. * @param fields Fields to cache.
*/ */
private void cacheFields(@Nullable GridDeployment dep, Class<?> cls, Class<? extends Annotation> annCls, private void cacheFields(@Nullable GridDeployment dep, Class<?> cls, Class<? extends Annotation> annCls,
List<GridResourceField> fields) { GridResourceField[] fields) {
if (dep != null) { if (dep != null) {
Set<Class<?>> classes = F.addIfAbsent(taskMap, dep.classLoader(), F.<Class<?>>newCSet()); Set<Class<?>> classes = F.addIfAbsent(taskMap, dep.classLoader(), F.<Class<?>>newCSet());


Expand All @@ -408,8 +414,8 @@ private void cacheFields(@Nullable GridDeployment dep, Class<?> cls, Class<? ext
classes.add(cls); classes.add(cls);
} }


Map<Class<? extends Annotation>, List<GridResourceField>> rsrcFields = Map<Class<? extends Annotation>, GridResourceField[]> rsrcFields =
F.addIfAbsent(fieldCache, cls, F.<Class<? extends Annotation>, List<GridResourceField>>newCMap()); F.addIfAbsent(fieldCache, cls, F.<Class<? extends Annotation>, GridResourceField[]>newCMap());


assert rsrcFields != null; assert rsrcFields != null;


Expand All @@ -423,8 +429,8 @@ private void cacheFields(@Nullable GridDeployment dep, Class<?> cls, Class<? ext
* @param annCls Annotation class for fields. * @param annCls Annotation class for fields.
* @return List of methods with given annotation, possibly {@code null}. * @return List of methods with given annotation, possibly {@code null}.
*/ */
@Nullable private List<GridResourceMethod> getMethodsFromCache(Class<?> cls, Class<? extends Annotation> annCls) { @Nullable private GridResourceMethod[] getMethodsFromCache(Class<?> cls, Class<? extends Annotation> annCls) {
Map<Class<? extends Annotation>, List<GridResourceMethod>> annCache = mtdCache.get(cls); Map<Class<? extends Annotation>, GridResourceMethod[]> annCache = mtdCache.get(cls);


return annCache != null ? annCache.get(annCls) : null; return annCache != null ? annCache.get(annCls) : null;
} }
Expand All @@ -438,7 +444,7 @@ private void cacheFields(@Nullable GridDeployment dep, Class<?> cls, Class<? ext
* @param mtds Methods to cache. * @param mtds Methods to cache.
*/ */
private void cacheMethods(@Nullable GridDeployment dep, Class<?> rsrcCls, Class<? extends Annotation> annCls, private void cacheMethods(@Nullable GridDeployment dep, Class<?> rsrcCls, Class<? extends Annotation> annCls,
List<GridResourceMethod> mtds) { GridResourceMethod[] mtds) {
if (dep != null) { if (dep != null) {
Set<Class<?>> classes = F.addIfAbsent(taskMap, dep.classLoader(), F.<Class<?>>newCSet()); Set<Class<?>> classes = F.addIfAbsent(taskMap, dep.classLoader(), F.<Class<?>>newCSet());


Expand All @@ -447,8 +453,8 @@ private void cacheMethods(@Nullable GridDeployment dep, Class<?> rsrcCls, Class<
classes.add(rsrcCls); classes.add(rsrcCls);
} }


Map<Class<? extends Annotation>, List<GridResourceMethod>> rsrcMtds = F.addIfAbsent(mtdCache, Map<Class<? extends Annotation>, GridResourceMethod[]> rsrcMtds = F.addIfAbsent(mtdCache,
rsrcCls, F.<Class<? extends Annotation>, List<GridResourceMethod>>newCMap()); rsrcCls, F.<Class<? extends Annotation>, GridResourceMethod[]>newCMap());


assert rsrcMtds != null; assert rsrcMtds != null;


Expand Down
Expand Up @@ -27,6 +27,9 @@
* Bean contains {@link Method} and {@link Annotation} for that method. * Bean contains {@link Method} and {@link Annotation} for that method.
*/ */
class GridResourceMethod { class GridResourceMethod {
/** */
static final GridResourceMethod[] EMPTY_ARRAY = new GridResourceMethod[0];

/** Method which used to inject resource. */ /** Method which used to inject resource. */
private final Method mtd; private final Method mtd;


Expand Down
Expand Up @@ -141,19 +141,19 @@ public void onUndeployed(GridDeployment dep) {
public void invokeAnnotated(GridDeployment dep, Object target, Class<? extends Annotation> annCls) public void invokeAnnotated(GridDeployment dep, Object target, Class<? extends Annotation> annCls)
throws IgniteCheckedException { throws IgniteCheckedException {
if (target != null) { if (target != null) {
Collection<Method> mtds = getMethodsWithAnnotation(dep, target.getClass(), annCls); GridResourceMethod[] rsrcMtds = ioc.getMethodsWithAnnotation(dep, target.getClass(), annCls);


if (mtds != null) { for (GridResourceMethod rsrcMtd : rsrcMtds) {
for (Method mtd : mtds) { Method mtd = rsrcMtd.getMethod();
try {
mtd.setAccessible(true); try {

mtd.setAccessible(true);
mtd.invoke(target);
} mtd.invoke(target);
catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) { }
throw new IgniteCheckedException("Failed to invoke annotated method [job=" + target + ", mtd=" + mtd + catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
", ann=" + annCls + ']', e); throw new IgniteCheckedException("Failed to invoke annotated method [job=" + target + ", mtd=" + mtd +
} ", ann=" + annCls + ']', e);
} }
} }
} }
Expand Down Expand Up @@ -569,35 +569,6 @@ public void injectBasicResource(Object target, Class<? extends Annotation> annCl
ioc.inject(target, annCls, new GridResourceBasicInjector<>(rsrc), null, null); ioc.inject(target, annCls, new GridResourceBasicInjector<>(rsrc), null, null);
} }


/**
* Gets list of methods in specified class annotated with specified annotation.
*
* @param dep Class deployment.
* @param rsrcCls Class to find methods in.
* @param annCls Annotation to find annotated methods with.
* @return List of annotated methods.
*/
@Nullable public Collection<Method> getMethodsWithAnnotation(GridDeployment dep, Class<?> rsrcCls,
Class<? extends Annotation> annCls) {
assert dep != null;
assert rsrcCls != null;
assert annCls != null;

List<GridResourceMethod> mtds = ioc.getMethodsWithAnnotation(dep, rsrcCls, annCls);

assert mtds != null;

if (!mtds.isEmpty()) {
return F.viewReadOnly(mtds, new C1<GridResourceMethod, Method>() {
@Override public Method apply(GridResourceMethod rsrcMtd) {
return rsrcMtd.getMethod();
}
});
}

return null;
}

/** /**
* Returns GridResourceIoc object. For tests only!!! * Returns GridResourceIoc object. For tests only!!!
* *
Expand Down

0 comments on commit 573b658

Please sign in to comment.