@Override
	public AggregateCount getCounts(String name, Interval interval, AggregateCountResolution resolution) {

		DateTime end = interval.getEnd();
		Chronology c = interval.getChronology();

		long[] counts;

		if (resolution == AggregateCountResolution.minute) {
			// Iterate through each hour in the interval and load the minutes for it
			MutableDateTime dt = new MutableDateTime(interval.getStart());
			dt.setRounding(c.hourOfDay());
			Duration step = Duration.standardHours(1);
			List<long[]> hours = new ArrayList<long[]>();
			while (dt.isBefore(end) || dt.isEqual(end)) {
				hours.add(getMinCountsForHour(name, dt));
				dt.add(step);
			}
			counts = MetricUtils.concatArrays(hours, interval.getStart().getMinuteOfHour(),
					interval.toPeriod().toStandardMinutes().getMinutes() + 1);

		}
		else if (resolution == AggregateCountResolution.hour) {
			DateTime cursor = new DateTime(c.dayOfMonth().roundFloor(interval.getStart().getMillis()));
			List<long[]> days = new ArrayList<long[]>();
			Duration step = Duration.standardHours(24);
			while (cursor.isBefore(end)) {
				days.add(getHourCountsForDay(name, cursor));
				cursor = cursor.plus(step);
			}

			counts = MetricUtils.concatArrays(days, interval.getStart().getHourOfDay(),
					interval.toPeriod().toStandardHours().getHours() + 1);

		}
		else if (resolution == AggregateCountResolution.day) {
			DateTime startDay = new DateTime(c.dayOfYear().roundFloor(interval.getStart().getMillis()));
			DateTime endDay = new DateTime(c.dayOfYear().roundFloor(end.plusDays(1).getMillis()));
			int nDays = Days.daysBetween(startDay, endDay).getDays();
			DateTime cursor = new DateTime(c.monthOfYear().roundFloor(interval.getStart().getMillis()));
			List<long[]> months = new ArrayList<long[]>();
			DateTime endMonth = new DateTime(c.monthOfYear().roundCeiling(interval.getEnd().plusMonths(1).getMillis()));
			while (cursor.isBefore(endMonth)) {
				months.add(getDayCountsForMonth(name, cursor));
				cursor = cursor.plusMonths(1);
			}

			counts = MetricUtils.concatArrays(months, interval.getStart().getDayOfMonth() - 1, nDays);
		}
		else if (resolution == AggregateCountResolution.month) {
			DateTime startMonth = new DateTime(c.monthOfYear().roundFloor(interval.getStartMillis()));
			DateTime endMonth = new DateTime(c.monthOfYear().roundFloor(end.plusMonths(1).getMillis()));
			int nMonths = Months.monthsBetween(startMonth, endMonth).getMonths();
			DateTime cursor = new DateTime(c.year().roundFloor(interval.getStartMillis()));
			List<long[]> years = new ArrayList<long[]>();
			DateTime endYear = new DateTime(c.year().roundCeiling(interval.getEnd().plusYears(1).getMillis()));
			while (cursor.isBefore(endYear)) {
				years.add(getMonthCountsForYear(name, cursor));
				cursor = cursor.plusYears(1);
			}

			counts = MetricUtils.concatArrays(years, interval.getStart().getMonthOfYear() - 1, nMonths);
		}
		else if (resolution == AggregateCountResolution.year) {
			DateTime startYear = new DateTime(interval.getStart().getYear(), 1, 1, 0, 0);
			DateTime endYear = new DateTime(end.getYear() + 1, 1, 1, 0, 0);
			int nYears = Years.yearsBetween(startYear, endYear).getYears();
			Map<String, Long> yearCounts = getYearCounts(name);
			counts = new long[nYears];

			for (int i = 0; i < nYears; i++) {
				int year = startYear.plusYears(i).getYear();
				Long count = yearCounts.get(Integer.toString(year));
				if (count == null) {
					count = 0L;
				}
				counts[i] = count;
			}
		}
		else {
			throw new IllegalStateException("Shouldn't happen. Unhandled resolution: " + resolution);
		}
		return new AggregateCount(name, interval, counts, resolution);
	}
For each query, we need to convert the interval into two variations. One is the start and end points rounded to
the resolution (used to calculate the number of entries to be returned from the query). The second is the start
and end buckets we have to retrieve which may contain entries for the interval. For example, when querying
at day resolution, the number of entries is the number of Joda time days between the start (rounded down to a
day boundary) and the end plus one day (also rounded down). However, we need load the data from the buckets
from the month the start day occurs in to the month end day occurs in. These are then concatenated, using the
start day as the start index into the first array, and writing the total number of entries in sequence from that
point into the combined result counts array.
spring-xd-analytics/src/main/java/org/springframework/xd/analytics/metrics/redis/RedisAggregateCounterRepository.java