/** * This software is licensed to you under the Apache License, Version 2.0 (the * "Apache License"). * * LinkedIn's contributions are made under the Apache License. If you contribute * to the Software, the contributions will be deemed to have been made under the * Apache License, unless you expressly indicate otherwise. Please do not make any * contributions that would be inconsistent with the Apache License. * * You may obtain a copy of the Apache License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, this software * distributed under the Apache License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Apache * License for the specific language governing permissions and limitations for the * software governed under the Apache License. * * © 2012 LinkedIn Corp. All Rights Reserved. */ package com.senseidb.search.node.broker; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.browseengine.bobo.api.BrowseSelection; import com.browseengine.bobo.facets.filter.FacetRangeFilter; import com.senseidb.indexing.activity.time.Clock; import com.senseidb.plugin.SenseiPlugin; import com.senseidb.plugin.SenseiPluginRegistry; import com.senseidb.search.req.SenseiRequest; public class LayeredTimeBasedPruner implements LayeredClusterPruner, SenseiPlugin { private static final String CLUSTERS = "clusters"; private List<String> clusters = new ArrayList<String>(); private Map<String, DateRange> clusterRanges = new HashMap<String, DateRange> (); private static final String TIME_COLUMN = "timeColumn"; private String timeColumn; private static class DateRange { private long startTime; private long endTime; public static DateRange valueOf(String dateStr) { String startTimeStr = dateStr.split("-")[0]; String endTimeStr = dateStr.split("-")[1]; DateRange ret = new DateRange(); ret.startTime = Long.parseLong(startTimeStr) * 24 * 60 * 60 * 1000; ret.endTime = Long.parseLong(endTimeStr) * 24 * 60 * 60 * 1000; return ret; } } @Override public void init(Map<String, String> config, SenseiPluginRegistry pluginRegistry) { String clustersConfig = config.get(CLUSTERS); timeColumn = config.get(TIME_COLUMN); if (timeColumn == null) { throw new IllegalArgumentException(TIME_COLUMN + " param should be present"); } if (clustersConfig == null) { throw new IllegalArgumentException(CLUSTERS + " param should be present"); } for (String cluster : clustersConfig.split(",")) { String trimmed = cluster.trim(); if (trimmed.length() > 0) { clusters.add(trimmed); String dayRange = config.get("daysRange." + trimmed); if (dayRange == null || dayRange.contains("-")) { throw new IllegalStateException("The dayRange should be specified for the cluster - " + trimmed + ". And it should have a format \"0-20\" where 0 and 20 are number of days"); } clusterRanges.put(trimmed, DateRange.valueOf(dayRange)); } } } @Override public void start() { } @Override public void stop() { } @Override public List<String> pruneClusters(SenseiRequest request, List<String> clusters) { BrowseSelection selection = request.getSelection(timeColumn); if (selection == null) { return clusters; } String[] rangeStrings = FacetRangeFilter.getRangeStrings(selection.getValues()[0]); final long start = getStartTime(rangeStrings); final long end = getEndTime(rangeStrings); List<String> ret = new ArrayList<String>(); for (String cluster : clusters) { DateRange clusterRange = clusterRanges.get(cluster); if (Clock.getTime() + clusterRange.startTime > end || Clock.getTime() + clusterRange.endTime < start) { //skipping cluster } else { ret.add(cluster); } } return ret; } @Override public boolean clusterPrioritiesEqual(SenseiRequest request) { return false; } public static long getStartTime(String[] rangeStrings) { long start; if ("*".equals(rangeStrings[0])) { start = Long.MIN_VALUE; } else { start = Long.parseLong(rangeStrings[0]); if ("true".equals(rangeStrings[2])) { start--; } } return start; } public static long getEndTime(String[] rangeStrings) { long end; if ("*".equals(rangeStrings[1])) { end = Long.MAX_VALUE; } else { end = Long.parseLong(rangeStrings[1]); if ("true".equals(rangeStrings[3])) { end++; } } return end; } }