001package org.cache2k.impl.timer;
002
003/*
004 * #%L
005 * cache2k core package
006 * %%
007 * Copyright (C) 2000 - 2015 headissue GmbH, Munich
008 * %%
009 * This program is free software: you can redistribute it and/or modify
010 * it under the terms of the GNU General Public License as
011 * published by the Free Software Foundation, either version 3 of the 
012 * License, or (at your option) any later version.
013 * 
014 * This program is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017 * GNU General Public License for more details.
018 * 
019 * You should have received a copy of the GNU General Public 
020 * License along with this program.  If not, see
021 * <http://www.gnu.org/licenses/gpl-3.0.html>.
022 * #L%
023 */
024
025/**
026 * @author Jens Wilke; created: 2014-03-22
027 */
028public class GlobalTimerService extends TimerService {
029
030  private static TimerService queue;
031
032  public static TimerService getInstance() {
033    if (queue  == null) {
034      queue = new GlobalTimerService(null, Runtime.getRuntime().availableProcessors() * 2);
035    }
036    return queue;
037  }
038
039  int racyRoundRobinCounter = 0;
040  ArrayHeapTimerQueue[] timerQueues;
041
042  public GlobalTimerService(String _managerName, int _threadCount) {
043    String _separator = "-";
044    if (_managerName != null) {
045      _separator = ":" + _managerName + ":";
046    }
047    timerQueues = new ArrayHeapTimerQueue[_threadCount];
048    for (int i = 0; i < timerQueues.length; i++) {
049      timerQueues[i] =
050        new ArrayHeapTimerQueue("cache2k" + _separator + "timer-" + i);
051    }
052  }
053
054  public <T> CancelHandle add(TimerPayloadListener<T> l, T _payload, long t) {
055    racyRoundRobinCounter = (racyRoundRobinCounter + 1) % timerQueues.length;
056    return timerQueues[racyRoundRobinCounter].add(l, _payload, t);
057  }
058
059  public CancelHandle add(TimerListener l, long t) {
060    racyRoundRobinCounter = (racyRoundRobinCounter + 1) % timerQueues.length;
061    return timerQueues[racyRoundRobinCounter].add(l, t);
062  }
063
064  @Override
065  public int getQueueSize() {
066    int v = 0;
067    for (int i = 0; i < timerQueues.length; i++) {
068      v += timerQueues[i].getQueueSize();
069    }
070    return v;
071  }
072
073  @Override
074  public long getEventsDelivered() {
075    long v = 0;
076    for (int i = 0; i < timerQueues.length; i++) {
077      v += timerQueues[i].getEventsDelivered();
078    }
079    return v;
080  }
081
082  @Override
083  public long getEventsScheduled() {
084    long v = 0;
085    for (int i = 0; i < timerQueues.length; i++) {
086      v += timerQueues[i].getEventsScheduled();
087    }
088    return v;
089  }
090
091  @Override
092  public long getPurgeCount() {
093    long v = 0;
094    for (int i = 0; i < timerQueues.length; i++) {
095      v += timerQueues[i].getPurgeCount();
096    }
097    return v;
098  }
099
100  @Override
101  public long getCancelCount() {
102    long v = 0;
103    for (int i = 0; i < timerQueues.length; i++) {
104      v += timerQueues[i].getCancelCount();
105    }
106    return v;
107  }
108
109  @Override
110  public long getFireExceptionCount() {
111    long v = 0;
112    for (int i = 0; i < timerQueues.length; i++) {
113      v += timerQueues[i].getFireExceptionCount();
114    }
115    return v;
116  }
117
118}