/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.jlab.hipo.data;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.jlab.hipo.schema.Schema;
import org.jlab.hipo.schema.SchemaFactory;
import org.jlab.hipo.utils.TextTable;
/**
*
* @author gavalian
*/
public class HipoEvent {
ByteBuffer eventBuffer = null;
//List eventIndex = new ArrayList();
private final Map groupsIndex = new HashMap();
private final SchemaFactory eventSchemaFactory = new SchemaFactory();
public HipoEvent(){
byte[] header = new byte[8];
header[0] = 'E';
header[1] = 'V';
header[2] = 'N';
header[3] = 'T';
eventBuffer = ByteBuffer.wrap(header);
eventBuffer.order(ByteOrder.LITTLE_ENDIAN);
}
public HipoEvent(SchemaFactory factory){
byte[] header = new byte[8];
header[0] = 'E';
header[1] = 'V';
header[2] = 'N';
header[3] = 'T';
eventBuffer = ByteBuffer.wrap(header);
eventBuffer.order(ByteOrder.LITTLE_ENDIAN);
eventSchemaFactory.copy(factory);
this.updateNodeIndex();
}
/**
* Initialize HipoEvent from a byte array.
* @param buffer
*/
public HipoEvent(byte[] buffer){
eventBuffer = ByteBuffer.wrap(buffer);
eventBuffer.order(ByteOrder.LITTLE_ENDIAN);
updateNodeIndex();
}
public HipoEvent(byte[] buffer, SchemaFactory factory){
eventBuffer = ByteBuffer.wrap(buffer);
eventBuffer.order(ByteOrder.LITTLE_ENDIAN);
updateNodeIndex();
eventSchemaFactory.copy(factory);
// this.eventSchemaFactory = factory;
}
/**
* Add a single node to the event.
* @param node HipoNode to add to the event.
*/
public void addNode(HipoNode node){
int nodeLength = node.getBufferSize();
int eventLength = eventBuffer.capacity();
byte[] dataBuffer = new byte[nodeLength+eventLength];
byte[] data = node.getBufferData();
int position = eventLength;
System.arraycopy(eventBuffer.array(), 0, dataBuffer, 0, eventLength);
System.arraycopy(data, 0, dataBuffer, position, node.getBufferSize());
/*
for(int i = 0; i < dataBuffer.length; i++){
System.out.print(String.format("%3X", dataBuffer[i]));
}*/
eventBuffer = ByteBuffer.wrap(dataBuffer);
eventBuffer.order(ByteOrder.LITTLE_ENDIAN);
}
/**
* Add the nodes in the list to the event.
* @param nodes list of HipoNode objects to add to the event.
*/
public void addNodes(List nodes){
int nodesLength = 0;
for(HipoNode node : nodes){
nodesLength += node.getBufferSize();
}
int eventLength = eventBuffer.capacity();
byte[] dataBuffer = new byte[nodesLength+eventLength];
// copy previous event, into the new byte array
System.arraycopy(eventBuffer.array(), 0, dataBuffer, 0, eventLength);
int position = eventLength;
for(HipoNode node : nodes){
byte[] data = node.getBufferData();
System.arraycopy(data, 0, dataBuffer, position, node.getBufferSize());
position += node.getBufferSize();
}
eventBuffer = ByteBuffer.wrap(dataBuffer);
eventBuffer.order(ByteOrder.LITTLE_ENDIAN);
this.updateNodeIndex();
}
/**
* updates the index of the
*/
public final void updateNodeIndex(){
int position = 8;
int capacity = eventBuffer.capacity();
//eventIndex.clear();
this.groupsIndex.clear();
int counter = 0;
while((position+8) adding group " + groupInt);
this.groupsIndex.put( groupInt, new GroupNodeIndexList(group));
}
this.groupsIndex.get(groupInt).addNodeIndex(idx);
//HipoNodeIndex index = new HipoNodeIndex();
//index.nodeGroup = group;
//index.nodeItem = item;
//index.nodeOffset = position;
//index.nodeLength = size;
//eventIndex.add(index);
position += 8 + size;
}
}
public void reset(){
byte[] header = new byte[8];
header[0] = 'E';
header[1] = 'V';
header[2] = 'N';
header[3] = 'T';
eventBuffer = ByteBuffer.wrap(header);
eventBuffer.order(ByteOrder.LITTLE_ENDIAN);
}
/**
* writes all the nodes in the group into the event.
* @param group group containing nodes
*/
public void writeGroup(HipoGroup group){
if(this.hasGroup(group.getSchema().getGroup())==true){
System.out.println("[HipoEvent] warning : groups is not added. The event contains group id = "
+ group.getSchema().getGroup() + " name = " + group.getSchema().getName());
} else {
List nodes = group.getNodes();
this.addNodes(nodes);
}
this.updateNodeIndex();
}
/**
* returns a group of nodes for given Schema.
* @param name name of the Schema
* @return group containing HipoNodes
*/
public HipoGroup getGroup(String name){
if(this.eventSchemaFactory.hasSchema(name)==true){
Schema schema = this.eventSchemaFactory.getSchema(name);
Map nodes = getGroup(schema.getGroup());
return new HipoGroup(nodes,schema);
}
return null;
}
/**
* Return string representation of the event.
* @return string printout of the event
*/
@Override
public String toString(){
StringBuilder str = new StringBuilder();
/*
str.append(String.format("EVENT (SIZE = %12d)\n",eventBuffer.capacity()));
for(HipoNodeIndex index : eventIndex){
str.append(index.toString());
str.append("\n");
}*/
str.append(toGroupListString());
return str.toString();
}
public byte[] getDataBuffer(){
return this.eventBuffer.array();
}
public void show(){
TextTable table = new TextTable("id:name:entries:group:items","4:36:12:9:9");
//System.out.println("+------------------------------------------------------------+");
Integer counter = 0;
for(Map.Entry entry : this.groupsIndex.entrySet()){
String name = "N/A";
if(this.eventSchemaFactory.hasSchema(entry.getKey())==true){
name = this.eventSchemaFactory.getSchema(entry.getKey()).getName();
}
Integer size = entry.getValue().getItemList().size();
HipoGroup group = this.getGroup(this.eventSchemaFactory.getSchema(entry.getKey()).getName());
Integer rows = group.getMaxSize();
table.addData(new String[]{counter.toString(), name, rows.toString(), entry.getKey().toString(),size.toString()});
//System.out.println(String.format("|%24d | %-24s | %5d |",
// entry.getKey(), name, entry.getValue().getItemList().size()));
counter++;
}
//System.out.println("+------------------------------------------------------------+");
System.out.println(table.toString());
}
public void showGroupByOrder(int order){
Integer counter = 0;
for(Map.Entry entry : this.groupsIndex.entrySet()){
if(counter==order){
int id = entry.getValue().getGroup();
this.showGroup(id);
}
counter++;
}
}
public void showGroup(int group){
Schema schema = getSchemaFactory().getSchema(group);
this.showGroup(schema.getName());
}
public void showGroup(String group){
if(this.hasGroup(group)==true){
HipoGroup bank = this.getGroup(group);
bank.show();
}
}
public HipoNode getNode(int group, int item){
if(this.groupsIndex.containsKey(group)==true){
GroupNodeIndexList list = groupsIndex.get(group);
if(list.hasItem(item)==true){
NodeIndexList nL = list.getItemIndex(item);
int nodeLength = 8 + nL.nodeLength;
byte[] array = new byte[nodeLength];
System.arraycopy(eventBuffer.array(), nL.nodeOffset, array, 0, nodeLength);
return new HipoNode(array);
}
}
/*
for(HipoNodeIndex index : eventIndex){
if(index.nodeGroup==group&&index.nodeItem==item){
int nodeLength = 8 + index.nodeLength;
byte[] array = new byte[nodeLength];
System.arraycopy(eventBuffer.array(), index.nodeOffset, array, 0, nodeLength);
return new HipoNode(array);
}
}*/
System.out.println("---> error : requested node ("
+ group + "," + item + ") is not found.");
return null;
}
public boolean hasGroup(int group){
return this.groupsIndex.containsKey(group);
}
public boolean hasGroup(String group){
if(this.eventSchemaFactory.hasSchema(group)){
if (this.eventSchemaFactory.getSchema(group) == null){
System.out.println("---> warning : schema for the group = "+ group +" is null.");
} else {
int groupId = this.eventSchemaFactory.getSchema(group).getGroup();
return this.groupsIndex.containsKey(groupId);
}
}
return false;
}
public SchemaFactory getSchemaFactory(){ return this.eventSchemaFactory;}
public List getGroups(){
List groups = new ArrayList();
for(Map.Entry entry : this.groupsIndex.entrySet()){
Map nodes = this.getGroup(entry.getKey());
Schema schema = this.getSchemaFactory().getSchema(entry.getKey());
if(schema!=null){
groups.add(new HipoGroup(nodes,schema));
} else {
groups.add(new HipoGroup(nodes));
}
}
return groups;
}
/**
* Removes given group with given group id from the event
* @param group
*/
public void removeGroup(int group){
if(this.hasGroup(group)==false) return;
List groups = getGroups();
reset();
this.groupsIndex.clear();
for(HipoGroup entry : groups){
if(entry.getSchema().getGroup()!=group){
//System.out.println("writing group " + entry.getSchema().getName());
this.writeGroup(entry);
}
}
this.updateNodeIndex();
}
/**
* removes group with given name from the event
* @param name
*/
public void removeGroup(String name){
if(this.hasGroup(name)==false) return;
Schema schema = this.eventSchemaFactory.getSchema(name);
if(schema!=null){
this.removeGroup(schema.getGroup());
}
}
public Map getGroup(int group){
Map groupNodes = new LinkedHashMap();
if(this.groupsIndex.containsKey(group)==true){
GroupNodeIndexList list = groupsIndex.get(group);
for(Map.Entry entry : list.getItemList().entrySet()){
int itemID = entry.getValue().nodeItem;
HipoNode node = this.getNode(group, itemID);
groupNodes.put(itemID, node);
}
}
/*for(HipoNodeIndex index : eventIndex){
if(index.nodeGroup==group){
HipoNode node = getNode(group,index.nodeItem);
groupNodes.put(index.nodeItem,node);
}
}*/
return groupNodes;
}
public String toGroupListString(){
StringBuilder str = new StringBuilder();
for(Map.Entry entry : this.groupsIndex.entrySet()){
str.append(entry.getValue().toString());
}
return str.toString();
}
public static class GroupNodeIndexList {
private int groupid = 0;
private final Map nodesIndex = new LinkedHashMap();
public GroupNodeIndexList(int gr){
groupid = gr;
}
public int getGroup(){
return groupid;
}
/**
* add a node index into the list. if the item already exists in the
* list a warning will be printed, and new item will not be added.
* @param indx node index list
*/
public void addNodeIndex(NodeIndexList indx){
//System.out.println("----------> adding " + indx.nodeItem);
if(nodesIndex.containsKey(indx.nodeItem)==true){
//System.out.println("[GroupNodeIndexList] --> error : group = "
// + groupid + " already has an item with id="+indx.nodeItem);
return;
}
nodesIndex.put(indx.nodeItem, indx);
}
/**
* returns map containing items in the group.
* @return map
*/
public Map getItemList(){
return this.nodesIndex;
}
public NodeIndexList getItemIndex(int item){
return this.nodesIndex.get(item);
}
public boolean hasItem(int item){
return this.nodesIndex.containsKey(item);
}
@Override
public String toString(){
StringBuilder str = new StringBuilder();
str.append(String.format("GROUP (%6d) \n", groupid));
for(Map.Entry entry : nodesIndex.entrySet()){
str.append("\t");
str.append(entry.getValue().toString());
str.append("\n");
}
return str.toString();
}
}
public static class NodeIndexList {
int nodeItem = 0;
int nodeOffset = 0;
int nodeLength = 0;
int nodeType = 0;
public NodeIndexList(int item, int offset, int length){
nodeItem = item;
nodeOffset = offset;
nodeLength = length;
}
@Override
public String toString(){
StringBuilder str = new StringBuilder();
str.append(String.format("ITEM (%4d) TYPE (%2d) LENGTH (%6d) OFFSET (%6d)",
nodeItem,nodeType,nodeLength,nodeOffset));
return str.toString();
}
public int getType(){return nodeType;}
public NodeIndexList setType(int type){ nodeType = type; return this;}
}
public static class HipoNodeIndex {
int nodeGroup = 0;
int nodeItem = 0;
int nodeOffset = 0;
int nodeLength = 0;
@Override
public String toString(){
StringBuilder str = new StringBuilder();
str.append(String.format("( %6d, %3d, %8d, %6d)",nodeGroup,nodeItem,nodeOffset,nodeLength));
return str.toString();
}
}
public static void main(String[] args){
HipoNode node = new HipoNode(1200,25,HipoNodeType.SHORT,5);
for(int i = 0; i < 5; i++) { node.setShort(i, (short) ((i+1)*2) );}
System.out.println(node.getHeaderString() + " : " + node.getDataString());
HipoNode nodeF = new HipoNode(1200,2,HipoNodeType.FLOAT,8);
for(int i = 0; i < 8; i++) { nodeF.setFloat(i, (float) ((i+1)*2.0+0.5) );}
System.out.println(nodeF.getHeaderString() + " : " + nodeF.getDataString());
List nodes = new ArrayList();
nodes.add(nodeF);
nodes.add(node);
//nodes.add(node);
HipoEvent event = new HipoEvent();
event.addNodes(nodes);
//event.addNode(node);
//event.addNode(nodeF);
event.updateNodeIndex();
System.out.println(event);
HipoNode nodeFLOAT = event.getNode(1200, 2);
System.out.println(nodeFLOAT.getHeaderString() + " : " + nodeFLOAT.getDataString());
HipoNode nodeSHORT = event.getNode(1200, 25);
System.out.println(nodeSHORT.getHeaderString() + " : " + nodeSHORT.getDataString());
Map group1200 = event.getGroup(1200);
System.out.println("-----------");
for(Map.Entry entry : group1200.entrySet()){
System.out.println(entry.getValue().getHeaderString() + " : " + entry.getValue().getDataString());
}
}
}
Ads help maintain this website.