/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.hadoop.chukwa.database; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.io.File; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class DatabaseConfig { private static Log log = LogFactory.getLog(DatabaseConfig.class); private Configuration config = null; public final static long CENTURY = 36500 * 24 * 60 * 60 * 1000L; public final static long DECADE = 3650 * 24 * 60 * 60 * 1000L; public final static long YEAR = 365 * 24 * 60 * 60 * 1000L; public final static long QUARTER = 91250 * 24 * 60 * 60L; public final static long MONTH = 30 * 24 * 60 * 60 * 1000L; public final static long WEEK = 7 * 24 * 60 * 60 * 1000L; public final static long DAY = 24 * 60 * 60 * 1000L; public final static String MDL_XML = "mdl.xml"; public DatabaseConfig(String path) { Path fileResource = new Path(path); config = new Configuration(); config.addResource(fileResource); } public DatabaseConfig() { String dataConfig = System.getenv("CHUKWA_CONF_DIR"); if (dataConfig == null) { dataConfig = MDL_XML; } else { dataConfig += File.separator + MDL_XML; } Path fileResource = new Path(dataConfig); config = new Configuration(); config.addResource(fileResource); } public String get(String key) { return config.get(key); } public void put(String key, String value) { this.config.set(key, value); } public Iterator<?> iterator() { return this.config.iterator(); } public HashMap<String, String> startWith(String key) { HashMap<String, String> transformer = new HashMap<String, String>(); Iterator<?> entries = config.iterator(); while (entries.hasNext()) { String entry = entries.next().toString(); if (entry.startsWith(key)) { String[] metrics = entry.split("="); transformer.put(metrics[0], metrics[1]); } } return transformer; } public String[] findTableName(String tableName, long start, long end) { String[] tableNames = null; String tableType = "_week"; long now = (new Date()).getTime(); long timeWindow = end - start; long partitionSize = WEEK; boolean fallback = true; if (config.get("consolidator.table." + tableName) == null) { tableNames = new String[1]; tableNames[0] = tableName; return tableNames; } if (timeWindow <= 0) { timeWindow = 1; } if (timeWindow > DECADE) { tableType = "_century"; partitionSize = CENTURY; } else if (timeWindow > YEAR) { tableType = "_decade"; partitionSize = DECADE; } else if (timeWindow > QUARTER) { tableType = "_year"; partitionSize = YEAR; } else if (timeWindow > MONTH) { tableType = "_quarter"; partitionSize = QUARTER; } else if (timeWindow > WEEK) { tableType = "_month"; partitionSize = MONTH; } else { tableType = "_week"; partitionSize = WEEK; } long currentPartition = now / partitionSize; long startPartition = start / partitionSize; long endPartition = end / partitionSize; while (fallback && partitionSize != CENTURY * 100) { // Check if the starting date is in the far distance from current time. If // it is, use down sampled data. if (startPartition + 2 < currentPartition) { fallback = true; if (partitionSize == DAY) { tableType = "_week"; partitionSize = WEEK; } else if (partitionSize == WEEK) { tableType = "_month"; partitionSize = MONTH; } else if (partitionSize == MONTH) { tableType = "_year"; partitionSize = YEAR; } else if (partitionSize == YEAR) { tableType = "_decade"; partitionSize = DECADE; } else if (partitionSize == DECADE) { tableType = "_century"; partitionSize = CENTURY; } else { partitionSize = 100 * CENTURY; } currentPartition = now / partitionSize; startPartition = start / partitionSize; endPartition = end / partitionSize; } else { fallback = false; } } if (startPartition != endPartition) { int delta = (int) (endPartition - startPartition); tableNames = new String[delta + 1]; for (int i = 0; i <= delta; i++) { long partition = startPartition + (long) i; tableNames[i] = tableName + "_" + partition + tableType; } } else { tableNames = new String[1]; tableNames[0] = tableName + "_" + startPartition + tableType; } return tableNames; } public String[] findTableNameForCharts(String tableName, long start, long end) { String[] tableNames = null; String tableType = "_week"; long now = (new Date()).getTime(); long timeWindow = end - start; if (timeWindow > 60 * 60 * 1000) { timeWindow = timeWindow + 1; } long partitionSize = WEEK; boolean fallback = true; if (config.get("consolidator.table." + tableName) == null) { tableNames = new String[1]; tableNames[0] = tableName; return tableNames; } if (timeWindow <= 0) { timeWindow = 1; } if (timeWindow > DECADE) { tableType = "_decade"; partitionSize = CENTURY; } else if (timeWindow > YEAR) { tableType = "_decade"; partitionSize = CENTURY; } else if (timeWindow > QUARTER) { tableType = "_decade"; partitionSize = DECADE; } else if (timeWindow > MONTH) { tableType = "_year"; partitionSize = YEAR; } else if (timeWindow > WEEK) { tableType = "_quarter"; partitionSize = QUARTER; } else if (timeWindow > DAY) { tableType = "_month"; partitionSize = MONTH; } else { tableType = "_week"; partitionSize = WEEK; } long currentPartition = now / partitionSize; long startPartition = start / partitionSize; long endPartition = end / partitionSize; while (fallback && partitionSize != DECADE * 100) { // Check if the starting date is in the far distance from current time. If // it is, use down sampled data. if (startPartition + 2 < currentPartition) { fallback = true; if (partitionSize == DAY) { tableType = "_month"; partitionSize = MONTH; } else if (partitionSize == WEEK) { tableType = "_quarter"; partitionSize = QUARTER; } else if (partitionSize == MONTH) { tableType = "_year"; partitionSize = YEAR; } else if (partitionSize == YEAR) { tableType = "_decade"; partitionSize = DECADE; } else { partitionSize = CENTURY; } currentPartition = now / partitionSize; startPartition = start / partitionSize; endPartition = end / partitionSize; } else { fallback = false; } } if (startPartition != endPartition) { int delta = (int) (endPartition - startPartition); tableNames = new String[delta + 1]; for (int i = 0; i <= delta; i++) { long partition = startPartition + (long) i; tableNames[i] = tableName + "_" + partition + tableType; } } else { tableNames = new String[1]; tableNames[0] = tableName + "_" + startPartition + tableType; } return tableNames; } public static void main(String[] args) { DatabaseConfig dbc = new DatabaseConfig(); String[] names = dbc.findTableName("system_metrics", 1216140020000L, 1218645620000L); for (String n : names) { System.out.println("name:" + n); } } }