com.anysoft.rrm.RRArchive Maven / Gradle / Ivy
package com.anysoft.rrm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.anysoft.util.Configurable;
import com.anysoft.util.JsonTools;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;
import com.anysoft.util.Reportable;
import com.anysoft.util.XMLConfigurable;
import com.anysoft.util.XmlElementProperties;
/**
* 环形数据归档
*
* @author duanyy
*
* @version 1.6.4.31 [20160128 duanyy]
* - 增加前序查询方法
*/
public class RRArchive implements Reportable,Configurable,XMLConfigurable {
/**
* 数据归档中的数据
*/
protected RRData [] rrds = null;
/**
* id
*/
protected String id;
/**
* 数据个数,缺省30个
*/
protected int rows = 30;
/**
* 每条数据的时间区域,60秒
*/
protected long step = 60 * 1000L;
public RRArchive(String rraId){
id = rraId;
}
/**
* 获取ID
* @return id
*/
public String getId(){
return id;
}
/**
* 获取数据个数
* @return 数据个数
*/
public int getRows(){return rows;}
/**
* 获取数据的时间区域
* @return 时间区域
*/
public long getStep(){return step;}
/**
* 更新RRA的数据
* @param fragment
*/
public synchronized void update(long t,D fragment){
long timestamp = (t / step)*step;
int index = (int)(timestamp/step) % rows;
if (rrds[index] == null){
//当前槽位是空的
rrds[index] = fragment.copy();
rrds[index].timestamp(timestamp);
}else{
//当前槽位不是空的
if (rrds[index].timestamp() < timestamp){
//有可能是前面时间周期的内容,覆盖掉
rrds[index] = fragment.copy();
rrds[index].timestamp(timestamp);
}else{
//有可能是当前周期的内容,在上面做加法
rrds[index].incr(fragment);
}
}
}
/**
* 获取迭代器,用于遍历数据
* @return 迭代器
*/
public Iterator iterator(){
return new MyIterator();
}
/**
* 获取当前周期数据
* @return data
*/
public RRData current(){
return get(System.currentTimeMillis());
}
/**
* 获取指定时间所对应的数据
* @param t 时间戳
* @return RRD数据
*/
public RRData get(long t){
long timestamp = (t / step)*step;
int index = (int)(timestamp/step) % rows;
if (rrds[index] == null){
//对应的槽位是空的
return null;
}else{
//对应槽位不是空的
if (rrds[index].timestamp() < timestamp){
return null;
}else{
return rrds[index];
}
}
}
/**
* 获取当前周期之前n个周期的数据
* @param n 周期数
* @return RRData数据
*/
public RRData previous(int n){
long now = System.currentTimeMillis();
return get(now - n * step);
}
public long now(){
return (System.currentTimeMillis() / step) * step;
}
@Override
public void report(Element xml) {
if (xml != null){
xml.setAttribute("id", id);
xml.setAttribute("rows", String.valueOf(rows));
xml.setAttribute("step", String.valueOf(step));
String detail = xml.getAttribute("hist");
if (detail != null && detail.equals("true")){ // NOSONAR
Document doc = xml.getOwnerDocument();
Iterator iter = iterator();
long now = now();
while (iter.hasNext()){
Element dElem = doc.createElement("d");
D d = iter.next();
if (d != null){ // NOSONAR
now = d.timestamp();
d.report(dElem);
}else{
now = now - step;
}
dElem.setAttribute("t", String.valueOf(now));
xml.appendChild(dElem);
}
}else{
//输出当前
Document doc = xml.getOwnerDocument();
Element curElem = doc.createElement("current");
long now = now();
RRData current = rrds[(int)(now() / step) % rows];
if (current != null){
current.report(curElem);
}
curElem.setAttribute("t", String.valueOf(now));
xml.appendChild(curElem);
}
}
}
@Override
public void report(Map json) {
if (json != null){
json.put("id", id);
json.put("rows", rows);
json.put("step", step);
boolean detail = JsonTools.getBoolean(json, "hist", false);
if (detail){
List