src/jdk.jfr/share/classes/jdk/jfr/consumer/StreamConfiguration.java
branchJEP-349-branch
changeset 58129 7b751fe181a5
parent 58020 f082177c5023
equal deleted inserted replaced
58121:6f8f18ac1d54 58129:7b751fe181a5
     1 package jdk.jfr.consumer;
     1 package jdk.jfr.consumer;
     2 
     2 
     3 import java.time.Instant;
     3 import java.time.Instant;
     4 import java.util.ArrayList;
     4 import java.util.ArrayList;
     5 import java.util.Arrays;
       
     6 import java.util.List;
     5 import java.util.List;
     7 import java.util.function.Consumer;
     6 import java.util.function.Consumer;
     8 
     7 
     9 import jdk.jfr.EventType;
     8 import jdk.jfr.consumer.Dispatcher.EventDispatcher;
    10 import jdk.jfr.consumer.AbstractEventStream.EventDispatcher;
       
    11 import jdk.jfr.internal.LongMap;
       
    12 import jdk.jfr.internal.Utils;
     9 import jdk.jfr.internal.Utils;
    13 import jdk.jfr.internal.consumer.InternalEventFilter;
       
    14 
    10 
    15 final class StreamConfiguration {
    11 final class StreamConfiguration {
    16     private static final Runnable[] NO_ACTIONS = new Runnable[0];
    12     final List<Runnable> closeActions = new ArrayList<>();
       
    13     final List<Runnable> flushActions = new ArrayList<>();
       
    14     final List<EventDispatcher> eventActions = new ArrayList<>();
       
    15     final List<Consumer<Throwable>> errorActions = new ArrayList<>();
    17 
    16 
    18     Consumer<?>[] errorActions = new Consumer<?>[0];
    17     boolean reuse = true;
    19     private Runnable[] flushActions = NO_ACTIONS;
    18     boolean ordered = true;
    20     private Runnable[] closeActions = NO_ACTIONS;
    19     Instant startTime = null;
    21     private EventDispatcher[] dispatchers = EventDispatcher.NO_DISPATCHERS;
    20     Instant endTime = null;
    22     private InternalEventFilter eventFilter = InternalEventFilter.ACCEPT_ALL;
    21     boolean started = false;
    23     LongMap<EventDispatcher[]> dispatcherLookup = new LongMap<>();
    22     long startNanos = 0;
       
    23     long endNanos = Long.MAX_VALUE;
    24 
    24 
    25     private boolean changedConfiguration = false;
    25     volatile boolean changed = true;
    26     private boolean closed = false;
       
    27     private boolean reuse = true;
       
    28     private boolean ordered = true;
       
    29     private Instant startTime = null;
       
    30     private Instant endTime = null;
       
    31     private boolean started = false;
       
    32     private long startNanos = 0;
       
    33     private long endNanos = Long.MAX_VALUE;
       
    34 
    26 
    35     // Cache the last event type and dispatch.
    27     public synchronized boolean remove(Object action) {
    36     EventType cacheEventType;
    28         boolean removed = false;
    37     EventDispatcher[] cacheDispatchers;
    29         removed |= flushActions.removeIf(e -> e == action);
    38 
    30         removed |= closeActions.removeIf(e -> e == action);
    39 
    31         removed |= errorActions.removeIf(e -> e == action);
    40     public StreamConfiguration(StreamConfiguration configuration) {
    32         removed |= eventActions.removeIf(e -> e.action == action);
    41         this.flushActions = configuration.flushActions;
    33         if (removed) {
    42         this.closeActions = configuration.closeActions;
    34             changed = true;
    43         this.errorActions = configuration.errorActions;
    35         }
    44         this.dispatchers = configuration.dispatchers;
    36         return removed;
    45         this.eventFilter = configuration.eventFilter;
       
    46         this.closed = configuration.closed;
       
    47         this.reuse = configuration.reuse;
       
    48         this.ordered = configuration.ordered;
       
    49         this.startTime = configuration.startTime;
       
    50         this.endTime = configuration.endTime;
       
    51         this.started = configuration.started;
       
    52         this.startNanos = configuration.startNanos;
       
    53         this.endNanos = configuration.endNanos;
       
    54         this.dispatcherLookup = configuration.dispatcherLookup;
       
    55     }
    37     }
    56 
    38 
    57     public StreamConfiguration() {
    39     public synchronized void addEventAction(String name, Consumer<RecordedEvent> consumer) {
       
    40         eventActions.add(new EventDispatcher(name, consumer));
       
    41         changed = true;
    58     }
    42     }
    59 
    43 
    60     public StreamConfiguration remove(Object action) {
    44     public void addEventAction(Consumer<RecordedEvent> action) {
    61         flushActions = remove(flushActions, action);
    45         addEventAction(null, action);
    62         closeActions = remove(closeActions, action);
       
    63         errorActions = remove(errorActions, action);
       
    64         dispatchers = removeDispatch(dispatchers, action);
       
    65         return this;
       
    66     }
    46     }
    67 
    47 
    68     public StreamConfiguration addDispatcher(EventDispatcher e) {
    48     public synchronized void addFlushAction(Runnable action) {
    69         dispatchers = add(dispatchers, e);
    49         flushActions.add(action);
    70         eventFilter = buildFilter(dispatchers);
    50         changed = true;
    71         dispatcherLookup = new LongMap<>();
       
    72         return this;
       
    73     }
    51     }
    74 
    52 
    75     public StreamConfiguration addFlushAction(Runnable action) {
    53     public synchronized void addCloseAction(Runnable action) {
    76         flushActions = add(flushActions, action);
    54         closeActions.add(action);
    77         return this;
    55         changed = true;
    78     }
    56     }
    79 
    57 
    80     public StreamConfiguration addCloseAction(Runnable action) {
    58     public synchronized void addErrorAction(Consumer<Throwable> action) {
    81         closeActions = add(closeActions, action);
    59         errorActions.add(action);
    82         return this;
    60         changed = true;
    83     }
    61     }
    84 
    62 
    85     public StreamConfiguration addErrorAction(Consumer<Throwable> action) {
    63     public synchronized void setReuse(boolean reuse) {
    86         errorActions = add(errorActions, action);
    64         this.reuse = reuse;
    87         return this;
    65         changed = true;
    88     }
    66     }
    89 
    67 
    90     public StreamConfiguration setClosed(boolean closed) {
    68     public synchronized void setOrdered(boolean ordered) {
    91         this.closed = closed;
    69         this.ordered = ordered;
    92         changedConfiguration = true;
    70         changed = true;
    93         return this;
       
    94     }
    71     }
    95 
    72 
    96     public boolean isClosed() {
    73     public synchronized void setEndTime(Instant endTime) {
    97         return closed;
    74         this.endTime = endTime;
       
    75         this.endNanos = Utils.timeToNanos(endTime);
       
    76         changed = true;
    98     }
    77     }
    99 
    78 
   100     public Runnable[] getCloseActions() {
    79     public synchronized void setStartTime(Instant startTime) {
   101         return closeActions;
    80         this.startTime = startTime;
       
    81         this.startNanos = Utils.timeToNanos(startTime);
       
    82         changed = true;
   102     }
    83     }
   103 
    84 
   104     public Runnable[] getFlushActions() {
    85     public synchronized void setStartNanos(long startNanos) {
   105         return flushActions;
    86         this.startNanos = startNanos;
       
    87         changed = true;
   106     }
    88     }
   107 
    89 
   108     private EventDispatcher[] removeDispatch(EventDispatcher[] array, Object action) {
    90     public synchronized void setStarted(boolean started) {
   109         List<EventDispatcher> list = new ArrayList<>(array.length);
       
   110         boolean modified = false;
       
   111         for (int i = 0; i < array.length; i++) {
       
   112             if (array[i].action != action) {
       
   113                 list.add(array[i]);
       
   114             } else {
       
   115                 modified = true;
       
   116             }
       
   117         }
       
   118         EventDispatcher[] result = list.toArray(new EventDispatcher[0]);
       
   119         if (modified) {
       
   120             eventFilter = buildFilter(result);
       
   121             dispatcherLookup = new LongMap<>();
       
   122             changedConfiguration = true;
       
   123         }
       
   124         return result;
       
   125     }
       
   126 
       
   127     private <T> T[] remove(T[] array, Object action) {
       
   128         List<T> list = new ArrayList<>(array.length);
       
   129         for (int i = 0; i < array.length; i++) {
       
   130             if (array[i] != action) {
       
   131                 list.add(array[i]);
       
   132             } else {
       
   133                 changedConfiguration = true;
       
   134             }
       
   135         }
       
   136         return list.toArray(array);
       
   137     }
       
   138 
       
   139     private <T> T[] add(T[] array, T object) {
       
   140         List<T> list = new ArrayList<>(Arrays.asList(array));
       
   141         list.add(object);
       
   142         changedConfiguration = true;
       
   143         return list.toArray(array);
       
   144     }
       
   145 
       
   146     private static InternalEventFilter buildFilter(EventDispatcher[] dispatchers) {
       
   147         InternalEventFilter ef = new InternalEventFilter();
       
   148         for (EventDispatcher ed : dispatchers) {
       
   149             String name = ed.eventName;
       
   150             if (name == null) {
       
   151                 return InternalEventFilter.ACCEPT_ALL;
       
   152             }
       
   153             ef.setThreshold(name, 0);
       
   154         }
       
   155         return ef;
       
   156     }
       
   157 
       
   158     public StreamConfiguration setReuse(boolean reuse) {
       
   159         this.reuse = reuse;
       
   160         changedConfiguration = true;
       
   161         return this;
       
   162     }
       
   163 
       
   164     public StreamConfiguration setOrdered(boolean ordered) {
       
   165         this.ordered = ordered;
       
   166         changedConfiguration = true;
       
   167         return this;
       
   168     }
       
   169 
       
   170     public StreamConfiguration setEndTime(Instant endTime) {
       
   171         this.endTime = endTime;
       
   172         this.endNanos = Utils.timeToNanos(endTime);
       
   173         changedConfiguration = true;
       
   174         return this;
       
   175     }
       
   176 
       
   177     public StreamConfiguration setStartTime(Instant startTime) {
       
   178         this.startTime = startTime;
       
   179         this.startNanos = Utils.timeToNanos(startTime);
       
   180         changedConfiguration = true;
       
   181         return this;
       
   182     }
       
   183 
       
   184     public Instant getStartTime() {
       
   185         return startTime;
       
   186     }
       
   187 
       
   188     public Object getEndTime() {
       
   189         return endTime;
       
   190     }
       
   191 
       
   192     public boolean isStarted() {
       
   193         return started;
       
   194     }
       
   195 
       
   196     public StreamConfiguration setStartNanos(long startNanos) {
       
   197         this.startNanos = startNanos;
       
   198         changedConfiguration = true;
       
   199         return this;
       
   200     }
       
   201 
       
   202     public void setStarted(boolean started) {
       
   203         this.started = started;
    91         this.started = started;
   204         changedConfiguration = true;
    92         changed = true;
   205     }
    93     }
   206 
    94 
   207     public boolean hasChanged() {
    95     public boolean hasChanged() {
   208         return changedConfiguration;
    96         return changed;
   209     }
    97     }
   210 
    98 
   211     public boolean getReuse() {
    99     public synchronized void clearChanged() {
   212         return reuse;
   100         changed = false;
   213     }
       
   214 
       
   215     public boolean getOrdered() {
       
   216         return ordered;
       
   217     }
       
   218 
       
   219     public InternalEventFilter getFiler() {
       
   220         return eventFilter;
       
   221     }
       
   222 
       
   223     public long getStartNanos() {
       
   224         return startNanos;
       
   225     }
       
   226 
       
   227     public long getEndNanos() {
       
   228         return endNanos;
       
   229     }
       
   230 
       
   231     public InternalEventFilter getFilter() {
       
   232         return eventFilter;
       
   233     }
       
   234 
       
   235     public void clearDispatchCache() {
       
   236         cacheDispatchers = null;
       
   237         cacheEventType = null;
       
   238     }
       
   239 
       
   240     public String toString() {
       
   241         StringBuilder sb = new StringBuilder();
       
   242         for (Runnable flush : flushActions) {
       
   243             sb.append("Flush Action: ").append(flush).append("\n");
       
   244         }
       
   245         for (Runnable close : closeActions) {
       
   246             sb.append("Close Action: " + close + "\n");
       
   247         }
       
   248         for (Consumer<?> error : errorActions) {
       
   249             sb.append("Error Action: " + error + "\n");
       
   250         }
       
   251         for (EventDispatcher dispatcher : dispatchers) {
       
   252             sb.append("Dispatch Action: " + dispatcher.eventName + "(" + dispatcher + ") \n");
       
   253         }
       
   254         sb.append("Closed: ").append(closed).append("\n");
       
   255         sb.append("Reuse: ").append(reuse).append("\n");
       
   256         sb.append("Ordered: ").append(ordered).append("\n");
       
   257         sb.append("Started: ").append(started).append("\n");
       
   258         sb.append("Start Time: ").append(startTime).append("\n");
       
   259         sb.append("Start Nanos: ").append(startNanos).append("\n");
       
   260         sb.append("End Time: ").append(endTime).append("\n");
       
   261         sb.append("End Nanos: ").append(endNanos).append("\n");
       
   262         return sb.toString();
       
   263     }
       
   264 
       
   265     EventDispatcher[] getDispatchers() {
       
   266         return dispatchers;
       
   267     }
   101     }
   268 }
   102 }