< prev index next >

core/org.openjdk.jmc.flightrecorder.rules/src/main/java/org/openjdk/jmc/flightrecorder/rules/util/RulesToolkit.java

Print this page




 128                 }
 129         };
 130         private final static LinearUnit MEBIBYTES = UnitLookup.MEMORY.getUnit(BinaryPrefix.MEBI);
 131 
 132         /**
 133          * Matches strings containing an identifiable version number as presented in a JVM info event.
 134          * The minimal matching form is "JRE (" followed by 1 to 4 numbers on the format a.b.c_d or
 135          * a.b.c.d. Examples are 1.7.0, 1.8.0_70, 9, 9.1, and 9.1.2.3. Match group 1 will contain the
 136          * matched version string.
 137          */
 138         private static final Pattern VERSION_PATTERN = Pattern
 139                         .compile(".*?JRE \\((\\d+(?:\\.\\d+(?:\\.\\d+(?:[\\._]\\d+)?)?)?(?:-ea)?).*"); //$NON-NLS-1$
 140 
 141         /**
 142          * Knowledge about the state of affairs of an event type in an IItemCollection.
 143          */
 144         public enum EventAvailability {
 145                 /**
 146                  * The type has events available in the collection.
 147                  */
 148                 AVAILABLE,
 149                 /**
 150                  * The type was actively enabled in the collection.
 151                  */
 152                 ENABLED,
 153                 /**
 154                  * The type was actively disabled in the collection.
 155                  */
 156                 DISABLED,
 157                 /**
 158                  * The type is known in the collection, but no events were found.
 159                  */
 160                 NONE,
 161                 /**
 162                  * The type is unknown in the collection.
 163                  */
 164                 UNAVAILABLE































 165         }
 166 
 167         /**
 168          * @return a least squares approximation of the increase in memory over the given time period,
 169          *         in mebibytes/second
 170          */
 171         public static double leastSquareMemory(
 172                 Iterator<? extends IItem> items, IMemberAccessor<IQuantity, IItem> timeField,
 173                 IMemberAccessor<IQuantity, IItem> memField) {
 174                 double sumX = 0;
 175                 double sumY = 0;
 176                 double sumX2 = 0;
 177                 double sumXY = 0;
 178                 double num = 0;
 179                 double startTime = 0;
 180 
 181                 while (items.hasNext()) {
 182                         IItem item = items.next();
 183                         long time = timeField.getMember(item).clampedLongValueIn(UnitLookup.EPOCH_S);
 184                         long mem = memField.getMember(item).clampedLongValueIn(MEBIBYTES);


 369          *            the collection to check.
 370          * @param typeIds
 371          *            the identifiers for the event types to check.
 372          * @return true if all of the required event types were known to be explicitly enabled.
 373          */
 374         public static boolean isEventsEnabled(IItemCollection items, String ... typeIds) {
 375                 IQuantity aggregate = items.apply(createEnablementFilter(true, typeIds)).getAggregate(Aggregators.count());
 376                 return aggregate != null && aggregate.longValue() == typeIds.length;
 377         }
 378 
 379         /**
 380          * This method returns false if any {@link EventAvailability} is disabled or unavailable.
 381          * Otherwise true.
 382          * 
 383          * @param eventAvailabilities
 384          *            the {@link EventAvailability} to check
 385          * @return false if any {@link EventAvailability} is disabled or unavailable. Otherwise true.
 386          */
 387         public static boolean isEventsEnabled(EventAvailability ... eventAvailabilities) {
 388                 for (EventAvailability availability : eventAvailabilities) {
 389                         if (availability == EventAvailability.DISABLED || availability == EventAvailability.UNAVAILABLE) {
 390                                 return false;
 391                         }
 392                 }
 393                 return true;
 394         }
 395 
 396         /**
 397          * This method checks if the provided event types were explicitly disabled by checking the
 398          * recording setting events.
 399          *
 400          * @param items
 401          *            the collection to check.
 402          * @param typeIds
 403          *            the identifiers for the event types to check.
 404          * @return true if all of the required event types were known to be explicitly enabled.
 405          */
 406         private static boolean isEventsDisabled(IItemCollection items, String ... typeIds) {
 407                 IQuantity aggregate = items.apply(createEnablementFilter(false, typeIds)).getAggregate(Aggregators.count());
 408                 return aggregate != null && aggregate.longValue() == typeIds.length;
 409         }


 419          *            the collection to check
 420          * @param typeIds
 421          *            the type identifiers to check
 422          * @return the availability for the event types
 423          */
 424         public static EventAvailability getEventAvailability(IItemCollection items, final String ... typeIds) {
 425                 // Only AVAILABLE if exactly all types have events
 426                 if (hasEvents(items, typeIds)) {
 427                         return EventAvailability.AVAILABLE;
 428                 }
 429                 // If enabled at any point, it was indeed enabled, and events could have been recorded
 430                 if (isEventsEnabled(items, typeIds)) {
 431                         return EventAvailability.ENABLED;
 432                 }
 433                 if (isEventsDisabled(items, typeIds)) {
 434                         return EventAvailability.DISABLED;
 435                 }
 436                 if (isEventsKnown(items, typeIds)) {
 437                         return EventAvailability.NONE;
 438                 }
 439                 return EventAvailability.UNAVAILABLE;














 440         }
 441 
 442         /**
 443          * Checks if the event types are known in the collection. Note that it does not necessarily mean
 444          * that there are events of the event type.
 445          *
 446          * @param items
 447          *            the collection to check
 448          * @param typeIds
 449          *            the event types to check
 450          * @return true if all the event types exists in the collection.
 451          */
 452         private static boolean isEventsKnown(IItemCollection items, String ... typeIds) {
 453                 Set<String> availableTypes = getAvailableTypeIds(items);
 454                 if (availableTypes.containsAll(Arrays.asList(typeIds))) {
 455                         return true;
 456                 }
 457                 return false;
 458         }
 459 


 491          * @return the result for the provided availability problem
 492          */
 493         public static Result getEventAvailabilityResult(
 494                 IRule rule, IItemCollection items, EventAvailability eventAvailability, String ... typeIds) {
 495                 switch (eventAvailability) {
 496                 case ENABLED:
 497                 case NONE:
 498                         String requiredEventsTypeNames = getEventTypeNames(items, typeIds);
 499                         return getNotApplicableResult(rule,
 500                                         MessageFormat.format(Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_EVENTS),
 501                                                         requiredEventsTypeNames),
 502                                         MessageFormat.format(Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_EVENTS_LONG),
 503                                                         rule.getName(), requiredEventsTypeNames));
 504                 case DISABLED:
 505                         String disabledEventTypeNames = getDisabledEventTypeNames(items, typeIds);
 506                         return getNotApplicableResult(rule,
 507                                         MessageFormat.format(Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_EVENT_TYPE),
 508                                                         disabledEventTypeNames),
 509                                         MessageFormat.format(Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_EVENT_TYPE_LONG),
 510                                                         rule.getName(), disabledEventTypeNames));
 511                 case UNAVAILABLE:
 512                         // Can't get type names if the event type is unavailable
 513                         List<String> quotedTypeIds = new ArrayList<>();
 514                         for (String typeId : typeIds) {
 515                                 quotedTypeIds.add("'" + typeId + "'"); //$NON-NLS-1$ //$NON-NLS-2$
 516                         }
 517                         Collections.sort(quotedTypeIds);
 518                         String unavailableTypeNames = StringToolkit.join(quotedTypeIds, ", "); //$NON-NLS-1$
 519                         return getNotApplicableResult(rule,
 520                                         MessageFormat.format(Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_UNAVAILABLE_EVENT_TYPE),
 521                                                         rule.getName(), unavailableTypeNames),
 522                                         MessageFormat.format(
 523                                                         Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_UNAVAILABLE_EVENT_TYPE_LONG),
 524                                                         rule.getName(), unavailableTypeNames));
 525                 case AVAILABLE:
 526                         String availableEventTypeNames = getEventTypeNames(items, typeIds);
 527                         return getNotApplicableResult(rule,
 528                                         MessageFormat.format(
 529                                                         Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_EVENT_TYPE_NOT_AVAILABLE),
 530                                                         availableEventTypeNames),
 531                                         MessageFormat.format(Messages.RulesToolkit_RULE_REQUIRES_EVENT_TYPE_NOT_AVAILABLE_LONG,




 128                 }
 129         };
 130         private final static LinearUnit MEBIBYTES = UnitLookup.MEMORY.getUnit(BinaryPrefix.MEBI);
 131 
 132         /**
 133          * Matches strings containing an identifiable version number as presented in a JVM info event.
 134          * The minimal matching form is "JRE (" followed by 1 to 4 numbers on the format a.b.c_d or
 135          * a.b.c.d. Examples are 1.7.0, 1.8.0_70, 9, 9.1, and 9.1.2.3. Match group 1 will contain the
 136          * matched version string.
 137          */
 138         private static final Pattern VERSION_PATTERN = Pattern
 139                         .compile(".*?JRE \\((\\d+(?:\\.\\d+(?:\\.\\d+(?:[\\._]\\d+)?)?)?(?:-ea)?).*"); //$NON-NLS-1$
 140 
 141         /**
 142          * Knowledge about the state of affairs of an event type in an IItemCollection.
 143          */
 144         public enum EventAvailability {
 145                                 /**
 146                                  * The type has events available in the collection.
 147                                  */
 148                                 AVAILABLE(4),
 149                                 /**
 150                                  * The type was actively enabled in the collection.
 151                                  */
 152                                 ENABLED(3),
 153                                 /**
 154                                  * The type was actively disabled in the collection.
 155                                  */
 156                                 DISABLED(2),
 157                                 /**
 158                                  * The type is known in the collection, but no events were found.
 159                                  */
 160                                 NONE(1),
 161                                 /**
 162                                  * The type is unknown in the collection.
 163                                  */
 164                                 UNKNOWN(0);
 165 
 166                 /*
 167                  * Used to determine the ordering of availabilities.
 168                  */
 169                 private final int availabilityScore;
 170 
 171                 EventAvailability(int availabilityScore) {
 172                         this.availabilityScore = availabilityScore;
 173                 }
 174 
 175                 /**
 176                  * Returns true if this EventAvailability is more available than the provided one.
 177                  * 
 178                  * @param availability
 179                  *            the {@link EventAvailability} to compare to.
 180                  * @return true if this EventAvailability is more available than the provided one.
 181                  */
 182                 public boolean isMoreAvailableThan(EventAvailability availability) {
 183                         return availabilityScore > availability.availabilityScore;
 184                 }
 185 
 186                 /**
 187                  * Returns true if this EventAvailability is less available than the provided one.
 188                  * 
 189                  * @param availability
 190                  *            the {@link EventAvailability} to compare to.
 191                  * @return true if this EventAvailability is less available than the provided one.
 192                  */
 193                 public boolean isLessAvailableThan(EventAvailability availability) {
 194                         return availabilityScore < availability.availabilityScore;
 195                 }
 196         }
 197 
 198         /**
 199          * @return a least squares approximation of the increase in memory over the given time period,
 200          *         in mebibytes/second
 201          */
 202         public static double leastSquareMemory(
 203                 Iterator<? extends IItem> items, IMemberAccessor<IQuantity, IItem> timeField,
 204                 IMemberAccessor<IQuantity, IItem> memField) {
 205                 double sumX = 0;
 206                 double sumY = 0;
 207                 double sumX2 = 0;
 208                 double sumXY = 0;
 209                 double num = 0;
 210                 double startTime = 0;
 211 
 212                 while (items.hasNext()) {
 213                         IItem item = items.next();
 214                         long time = timeField.getMember(item).clampedLongValueIn(UnitLookup.EPOCH_S);
 215                         long mem = memField.getMember(item).clampedLongValueIn(MEBIBYTES);


 400          *            the collection to check.
 401          * @param typeIds
 402          *            the identifiers for the event types to check.
 403          * @return true if all of the required event types were known to be explicitly enabled.
 404          */
 405         public static boolean isEventsEnabled(IItemCollection items, String ... typeIds) {
 406                 IQuantity aggregate = items.apply(createEnablementFilter(true, typeIds)).getAggregate(Aggregators.count());
 407                 return aggregate != null && aggregate.longValue() == typeIds.length;
 408         }
 409 
 410         /**
 411          * This method returns false if any {@link EventAvailability} is disabled or unavailable.
 412          * Otherwise true.
 413          * 
 414          * @param eventAvailabilities
 415          *            the {@link EventAvailability} to check
 416          * @return false if any {@link EventAvailability} is disabled or unavailable. Otherwise true.
 417          */
 418         public static boolean isEventsEnabled(EventAvailability ... eventAvailabilities) {
 419                 for (EventAvailability availability : eventAvailabilities) {
 420                         if (availability == EventAvailability.DISABLED || availability == EventAvailability.UNKNOWN) {
 421                                 return false;
 422                         }
 423                 }
 424                 return true;
 425         }
 426 
 427         /**
 428          * This method checks if the provided event types were explicitly disabled by checking the
 429          * recording setting events.
 430          *
 431          * @param items
 432          *            the collection to check.
 433          * @param typeIds
 434          *            the identifiers for the event types to check.
 435          * @return true if all of the required event types were known to be explicitly enabled.
 436          */
 437         private static boolean isEventsDisabled(IItemCollection items, String ... typeIds) {
 438                 IQuantity aggregate = items.apply(createEnablementFilter(false, typeIds)).getAggregate(Aggregators.count());
 439                 return aggregate != null && aggregate.longValue() == typeIds.length;
 440         }


 450          *            the collection to check
 451          * @param typeIds
 452          *            the type identifiers to check
 453          * @return the availability for the event types
 454          */
 455         public static EventAvailability getEventAvailability(IItemCollection items, final String ... typeIds) {
 456                 // Only AVAILABLE if exactly all types have events
 457                 if (hasEvents(items, typeIds)) {
 458                         return EventAvailability.AVAILABLE;
 459                 }
 460                 // If enabled at any point, it was indeed enabled, and events could have been recorded
 461                 if (isEventsEnabled(items, typeIds)) {
 462                         return EventAvailability.ENABLED;
 463                 }
 464                 if (isEventsDisabled(items, typeIds)) {
 465                         return EventAvailability.DISABLED;
 466                 }
 467                 if (isEventsKnown(items, typeIds)) {
 468                         return EventAvailability.NONE;
 469                 }
 470                 return EventAvailability.UNKNOWN;
 471         }
 472 
 473         /**
 474          * Returns the lowest availability from the ones provided. See {@link EventAvailability}.
 475          */
 476         public static EventAvailability getLeastAvailable(EventAvailability ... availabilites) {
 477                 EventAvailability lowest = EventAvailability.AVAILABLE;
 478 
 479                 for (EventAvailability availability : availabilites) {
 480                         if (availability.isLessAvailableThan(lowest)) {
 481                                 lowest = availability;
 482                         }
 483                 }
 484                 return lowest;
 485         }
 486 
 487         /**
 488          * Checks if the event types are known in the collection. Note that it does not necessarily mean
 489          * that there are events of the event type.
 490          *
 491          * @param items
 492          *            the collection to check
 493          * @param typeIds
 494          *            the event types to check
 495          * @return true if all the event types exists in the collection.
 496          */
 497         private static boolean isEventsKnown(IItemCollection items, String ... typeIds) {
 498                 Set<String> availableTypes = getAvailableTypeIds(items);
 499                 if (availableTypes.containsAll(Arrays.asList(typeIds))) {
 500                         return true;
 501                 }
 502                 return false;
 503         }
 504 


 536          * @return the result for the provided availability problem
 537          */
 538         public static Result getEventAvailabilityResult(
 539                 IRule rule, IItemCollection items, EventAvailability eventAvailability, String ... typeIds) {
 540                 switch (eventAvailability) {
 541                 case ENABLED:
 542                 case NONE:
 543                         String requiredEventsTypeNames = getEventTypeNames(items, typeIds);
 544                         return getNotApplicableResult(rule,
 545                                         MessageFormat.format(Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_EVENTS),
 546                                                         requiredEventsTypeNames),
 547                                         MessageFormat.format(Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_EVENTS_LONG),
 548                                                         rule.getName(), requiredEventsTypeNames));
 549                 case DISABLED:
 550                         String disabledEventTypeNames = getDisabledEventTypeNames(items, typeIds);
 551                         return getNotApplicableResult(rule,
 552                                         MessageFormat.format(Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_EVENT_TYPE),
 553                                                         disabledEventTypeNames),
 554                                         MessageFormat.format(Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_EVENT_TYPE_LONG),
 555                                                         rule.getName(), disabledEventTypeNames));
 556                 case UNKNOWN:
 557                         // Can't get type names if the event type is unavailable
 558                         List<String> quotedTypeIds = new ArrayList<>();
 559                         for (String typeId : typeIds) {
 560                                 quotedTypeIds.add("'" + typeId + "'"); //$NON-NLS-1$ //$NON-NLS-2$
 561                         }
 562                         Collections.sort(quotedTypeIds);
 563                         String unavailableTypeNames = StringToolkit.join(quotedTypeIds, ", "); //$NON-NLS-1$
 564                         return getNotApplicableResult(rule,
 565                                         MessageFormat.format(Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_UNAVAILABLE_EVENT_TYPE),
 566                                                         rule.getName(), unavailableTypeNames),
 567                                         MessageFormat.format(
 568                                                         Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_UNAVAILABLE_EVENT_TYPE_LONG),
 569                                                         rule.getName(), unavailableTypeNames));
 570                 case AVAILABLE:
 571                         String availableEventTypeNames = getEventTypeNames(items, typeIds);
 572                         return getNotApplicableResult(rule,
 573                                         MessageFormat.format(
 574                                                         Messages.getString(Messages.RulesToolkit_RULE_REQUIRES_EVENT_TYPE_NOT_AVAILABLE),
 575                                                         availableEventTypeNames),
 576                                         MessageFormat.format(Messages.RulesToolkit_RULE_REQUIRES_EVENT_TYPE_NOT_AVAILABLE_LONG,


< prev index next >