/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package TCM_MPI.CLS;
import TCM_MPI.Buffer.BufferInfo;
import TCM_MPI.Buffer.Events.BufferEvent;
import TCM_MPI.Buffer.Events.BufferListener;
import TCM_MPI.CheckClasses.CheckData_JvmTcp;
import TCM_MPI.Interfaces.TCM_MPI_Interface;
import TCM_MPI.SenderClasses.ItemsProcess;
import TCM_MPI.SenderClasses.ProcessSender;
import TCM_MPI.SenderClasses.SendData_JvmTcp;
import TCM_MPI.Sockets.Interfaces.ISocketTcm;
import TCM_MPI.Sockets.SocketJvm;
import java.nio.ByteBuffer;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*
* @author cpd
*
* */
public class TCM_MPI_TCP implements TCM_MPI_Interface,BufferListener{
private ISocketTcm ISOCKET;
private Thread _THREAD_CHECK;
private Thread _THREAD_SEND;
private ArrayBlockingQueue<TcmByteData> _SEND_QUEUE;
private BufferInfo TCM_BUFFER;
private int TCM_ID;
private ExecutorService THREAD_POOL;
@SuppressWarnings({"CallToThreadStartDuringObjectConstruction", "empty-statement", "SleepWhileInLoop", "LeakingThisInConstructor"})
public TCM_MPI_TCP(int ID,String SERVER_IP,int POR_SERVER) throws Exception {
this.TCM_ID = ID;
this.ISOCKET = new SocketJvm();
while(this.ISOCKET.Connect(SERVER_IP, 12345) != true){
System.out.println("NÃO CONECTADO ...");
Thread.sleep(1000);
}
this.ISOCKET.SendCount(ID);
this.ISOCKET.setReceiveTimeout(2000);
this.ISOCKET.setReceiveBufferSize(CONST.BUFFER_SIZE * 8);
this.ISOCKET.setSendBufferSize(CONST.BUFFER_SIZE * 8);
this.TCM_BUFFER = new BufferInfo();
this.TCM_BUFFER.addBufferListener(this);
this._SEND_QUEUE = new ArrayBlockingQueue<TcmByteData>(2048);
this.THREAD_POOL = Executors.newFixedThreadPool(16);
SendData_JvmTcp SENDER = new SendData_JvmTcp(_SEND_QUEUE,this.ISOCKET);
CheckData_JvmTcp CHECK = new CheckData_JvmTcp(this.ISOCKET, TCM_BUFFER, THREAD_POOL);
this._THREAD_CHECK = new Thread(SENDER);
this._THREAD_CHECK.start();
this._THREAD_SEND = new Thread(CHECK);
this._THREAD_SEND.start();
}
/**
* Retorna um array de N bytes recebido vindo de FROM
*
* @param FROM int - id do remetente
* @param N int - numero de bytes a receber
* @return byte[] - array de bytes recebido
* @throws Exception - dispara caso ocorra algum erro no processo
*/
@Override
@SuppressWarnings("SleepWhileInLoop")
public byte[] TCM_RECV_BYTE(int FROM, int N) throws Exception {
while(!this.TCM_BUFFER.IsExistData(FROM, CONST.ID_TYPE_BYTE)){
Thread.sleep(CONST.SLEEP_SEND_TIME);
}
ByteBuffer BFF = this.TCM_BUFFER.GetData(FROM, CONST.ID_TYPE_BYTE);
return BFF.array();
}
/**
* Retorna um array de N chars recebido vindo de FROM
*
* @param FROM int - id do remetente
* @param N int - numero de char a receber
* @return char[] - array de char recebido
* @throws Exception - dispara caso ocorra algum erro no processo
*/
@Override
@SuppressWarnings("SleepWhileInLoop")
public char[] TCM_RECV_CHAR(int FROM, int N) throws Exception {
while(!this.TCM_BUFFER.IsExistData(FROM,CONST.ID_TYPE_CHAR)){
Thread.sleep(CONST.SLEEP_SEND_TIME);
}
char NEW[] = null;
ByteBuffer BFF = this.TCM_BUFFER.GetData(FROM, CONST.ID_TYPE_CHAR);
if(BFF != null){
NEW = new char[N];
for(int x=0 , inc=0 ; x < N ; x+=2 , inc++){
NEW[inc] = BFF.getChar(x);
}
}
return NEW;
}
/**
* Retorna um array de N inteiros recebido vindo de FROM
*
* @param FROM int - id do remetente
* @param N int - numero de inteiros a receber
* @return int[] - array de int recebido
* @throws Exception - dispara caso ocorra algum erro no processo
*/
@Override
@SuppressWarnings("SleepWhileInLoop")
public int[] TCM_RECV_INT(int FROM, int N) throws Exception {
while(!this.TCM_BUFFER.IsExistData(FROM,CONST.ID_TYPE_INTEGER)){
Thread.sleep(CONST.SLEEP_SEND_TIME);
}
int NEW[] = null;
ByteBuffer BFF = this.TCM_BUFFER.GetData(FROM, CONST.ID_TYPE_INTEGER);
if(BFF != null){
NEW = new int[N];
for(int x=0 , inc=0 ; inc < N ; x+=4 , inc++){
NEW[inc] = BFF.getInt(x);
}
}
return NEW;
}
/**
* Retorna um array de N doubles recebido vindo de FROM
*
* @param FROM int - id do remetente
* @param N int - numero de double a receber
* @return double[] - array de double recebido
* @throws Exception - dispara caso ocorra algum erro no processo
*/
@Override
@SuppressWarnings("SleepWhileInLoop")
public double[] TCM_RECV_DOUBLE(int FROM, int N) throws Exception {
while(!this.TCM_BUFFER.IsExistData(FROM,CONST.ID_TYPE_DOUBLE)){
Thread.sleep(CONST.SLEEP_SEND_TIME);
}
double NEW[] = null;
ByteBuffer BFF = this.TCM_BUFFER.GetData(FROM, CONST.ID_TYPE_DOUBLE);
if(BFF != null){
NEW = new double[N];
for(int x=0 , inc=0 ; x < N ; x+=8 , inc++){
NEW[inc] = BFF.getDouble(x);
}
}
return NEW;
}
/**
* Envia um array de N Bytes especificado por BY para<br>
* o destinatario FROM
*
* @param BY byte[] - array a ser enviado
* @param DEST int - id do destinatario
* @param N int - quantidade de bytes a enviar
* @throws Exception - disparado caso ocorra algum erro no processo
*/
@Override
public void TCM_SEND_BYTE(byte[] BY, int DEST, int N) throws Exception {
if(BY == null){
throw new NullPointerException("referência de Array nulo");
}
if(N <= 0 || N > BY.length || BY.length == 0){
throw new ArrayIndexOutOfBoundsException("você quer acesar um indice não existente");
}
if(N > CONST.MAX_ARRAY_LEN){
throw new ArrayIndexOutOfBoundsException("você ultrapassou o limite maximo de um array");
}
ItemsProcess ITEM_PROC = new ItemsProcess();
ITEM_PROC._SEND_QUEUE = this._SEND_QUEUE;
ITEM_PROC._DEST_ID = DEST;
ITEM_PROC._PROC_ID = this.TCM_ID;
ITEM_PROC._TYPE_ID = CONST.ID_TYPE_BYTE;
ITEM_PROC._NUMBER_TO_SEND = N;
ITEM_PROC._BYTES = BY;
ProcessSender proc_send = new ProcessSender(ITEM_PROC);
proc_send.run();
}
/**
* Envia um array de N chars especificado por CHR para<br>
* o destinatario FROM
*
* @param CHR char[] - array a ser enviado
* @param DEST int - id do destinatario
* @param N int - quantidade de chars a enviar
* @throws Exception - disparado caso ocorra algum erro no processo
*/
@Override
public void TCM_SEND_CHAR(char[] CHR, int DEST, int N) throws Exception {
if(CHR == null){
throw new NullPointerException("referência de Array nulo");
}
if(N <= 0 || N > CHR.length || CHR.length == 0){
throw new ArrayIndexOutOfBoundsException("você quer acesar um indice não existente");
}
if(N > CONST.MAX_ARRAY_LEN){
throw new ArrayIndexOutOfBoundsException("você ultrapassou o limite maximo de um array");
}
ItemsProcess ITEM_PROC = new ItemsProcess();
ITEM_PROC._SEND_QUEUE = this._SEND_QUEUE;
ITEM_PROC._DEST_ID = DEST;
ITEM_PROC._PROC_ID = this.TCM_ID;
ITEM_PROC._TYPE_ID = CONST.ID_TYPE_CHAR;
ITEM_PROC._NUMBER_TO_SEND = N;
ITEM_PROC._CHAR = CHR;
ProcessSender proc_send = new ProcessSender(ITEM_PROC);
proc_send.run();
}
/**
* Envia um array de N inteiros especificado por INTS para<br>
* o destinatario FROM
*
* @param INTS int[] - array a ser enviado
* @param DEST int - id do destinatario
* @param N int - quantidade de inteiros a enviar
* @throws Exception - disparado caso ocorra algum erro no processo
*/
@Override
public synchronized void TCM_SEND_INT(int[] INTS, int DEST, int N) throws Exception {
if(INTS == null){
throw new NullPointerException("referência de Array nulo");
}
if(N <= 0 || N > INTS.length || INTS.length == 0){
throw new ArrayIndexOutOfBoundsException("você quer acesar um indice não existente");
}
if(N > CONST.MAX_ARRAY_LEN){
throw new ArrayIndexOutOfBoundsException("você ultrapassou o limite maximo de um array");
}
ItemsProcess ITEM_PROC = new ItemsProcess();
ITEM_PROC._SEND_QUEUE = this._SEND_QUEUE;
ITEM_PROC._DEST_ID = DEST;
ITEM_PROC._PROC_ID = this.TCM_ID;
ITEM_PROC._TYPE_ID = CONST.ID_TYPE_INTEGER;
ITEM_PROC._NUMBER_TO_SEND = N;
ITEM_PROC._INTEGER = INTS;
ProcessSender proc_send = new ProcessSender(ITEM_PROC);
proc_send.run();
}
/**
* Envia um array de N doubles especificado por DBL para<br>
* o destinatario FROM
*
* @param DBL double[] - array a ser enviado
* @param DEST int - id do destinatario
* @param N int - quantidade de doubles a enviar
* @throws Exception - disparado caso ocorra algum erro no processo
*/
@Override
public void TCM_SEND_DOUBLE(double[] DBL, int DEST, int N) throws Exception {
if(DBL == null){
throw new NullPointerException("referência de Array nulo");
}
if(N <= 0 || N > DBL.length || DBL.length == 0){
throw new ArrayIndexOutOfBoundsException("você quer acesar um indice não existente");
}
if(N > CONST.MAX_ARRAY_LEN){
throw new ArrayIndexOutOfBoundsException("você ultrapassou o limite maximo de um array");
}
ItemsProcess ITEM_PROC = new ItemsProcess();
ITEM_PROC._SEND_QUEUE = this._SEND_QUEUE;
ITEM_PROC._DEST_ID = DEST;
ITEM_PROC._PROC_ID = this.TCM_ID;
ITEM_PROC._TYPE_ID = CONST.ID_TYPE_DOUBLE;
ITEM_PROC._NUMBER_TO_SEND = N;
ITEM_PROC._DOUBLE = DBL;
ProcessSender proc_send = new ProcessSender(ITEM_PROC);
proc_send.run();
}
/**
* Disparado na escuta pelo buffer
*
* @param e BufferEvent - disparador do evento
* @param key String - chave recebida
*/
@Override
public void BufferInfoReceived(BufferEvent e, String key) {
System.out.println("BufferData >> Info recebida { " + key + " }");
}
/**
* Disparado na escuta pelo buffer
*
* @param e BufferEvent - disparador do evento
* @param key String - chave deletada
*/
@Override
public void BufferInfoDeleted(BufferEvent e, String key) {
System.out.println("BufferData >> Info deletada { " + key + " }");
}
}