/**
* CopyRight by Chinamobile
*
* MessageQueuesForBDB.java
*/
package com.chinamobile.bcbsp.comm;
import java.io.File;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.chinamobile.bcbsp.util.BSPJob;
import com.chinamobile.bcbsp.util.BSPJobID;
/**
* @author root
* Message queues manager for BerkeleyDB Java Edition supported.
*/
public class MessageQueuesForBDB implements MessageQueuesInterface {
@SuppressWarnings("unused")
private static final Log LOG = LogFactory.getLog(MessageQueuesForBDB.class);
private BSPJobID jobID;
private int partitionID;
private File fileRoot;
private File messagesDataFile;
private int nextOutgoingQueueCount = 1;
private ConcurrentHashMap<String, ConcurrentLinkedQueue<BSPMessage>> outgoingQueues = new ConcurrentHashMap<String, ConcurrentLinkedQueue<BSPMessage>>();
private BDBMap<String, String> incomingQueues = null;
private BDBMap<String, String> incomedQueues = null;
class BSPMessageWithUniqueID{
String msg = null;
String uniqueID = null;
public BSPMessageWithUniqueID(String msg, String uniqueID) {
this.msg = msg;
this.uniqueID = uniqueID;
}
}
public MessageQueuesForBDB(BSPJob job, int partitionID){
this.jobID = job.getJobID();
this.partitionID = partitionID;
this.fileRoot = new File("/tmp/bcbsp/messagedata/" + this.jobID.toString() + "/"
+ "partition-" + this.partitionID);
this.messagesDataFile = new File(this.fileRoot + "/" + "messagesData");
if(!fileRoot.exists()){
fileRoot.mkdirs();
}
if(!messagesDataFile.exists()){
messagesDataFile.mkdirs();
}
this.incomingQueues =new BDBMap<String, String>(
job,
messagesDataFile,
"incomingQueues",
String.class,
String.class);
this.incomedQueues =new BDBMap<String, String>(
job,
messagesDataFile,
"incomedQueues",
String.class,
String.class);
}
@Override
public void clearAllQueues() {
clearIncomedQueues();
clearIncomingQueues();
clearOutgoingQueues();
this.incomingQueues.shutdown();
this.incomedQueues.shutdown();
deleteFile(this.messagesDataFile.toString());
}
@Override
public void clearIncomedQueues() {
this.incomedQueues.clear();
}
@Override
public void clearIncomingQueues() {
this.incomingQueues.clear();
}
@Override
public void clearOutgoingQueues() {
this.outgoingQueues.clear();
}
@Override
public void exchangeIncomeQueues() {
clearIncomedQueues();
BDBMap<String, String> tempQueues = this.incomedQueues;
this.incomedQueues = this.incomingQueues;
this.incomingQueues = tempQueues;
}
@Override
public int getIncomedQueuesSize() {
return incomedQueues.size();
}
@Override
public int getIncomingQueuesSize() {
return incomingQueues.size();
}
@Override
public String getMaxIncomingQueueIndex() {
return null;
}
@Override
public String getMaxOutgoingQueueIndex() {
int maxSize = 0;
String maxIndex = null;
ConcurrentLinkedQueue<BSPMessage> tempQueue = null;
Entry<String, ConcurrentLinkedQueue<BSPMessage>> entry = null;
Iterator<Entry<String, ConcurrentLinkedQueue<BSPMessage>>> it =
this.outgoingQueues.entrySet().iterator();
while (it.hasNext()) { // Get the queue with the max size
entry = it.next();
tempQueue = entry.getValue();
if (tempQueue.size() > maxSize) {
maxSize = tempQueue.size();
maxIndex = entry.getKey();
} // if
} // while
return maxIndex;
}
@Override
public int getOutgoingQueuesSize() {
int size = 0;
Entry<String, ConcurrentLinkedQueue<BSPMessage>> entry;
Iterator<Entry<String, ConcurrentLinkedQueue<BSPMessage>>> it = this.outgoingQueues
.entrySet().iterator();
ConcurrentLinkedQueue<BSPMessage> queue;
while (it.hasNext()) {
entry = it.next();
queue = entry.getValue();
size += queue.size();
}
return size;
}
@Override
public void incomeAMessage(String dstVertexID, BSPMessage msg) {
StringBuffer unique = new StringBuffer();
unique.append(incomingQueues.size());
unique.append("$");
unique.append(msg.intoString());
incomingQueues.put(dstVertexID, unique.toString());
}
@Override
public void outgoAMessage(String outgoingIndex, BSPMessage msg) {
ConcurrentLinkedQueue<BSPMessage> outgoingQueue = outgoingQueues.get(outgoingIndex);
if (outgoingQueue == null) {
outgoingQueue = new ConcurrentLinkedQueue<BSPMessage>();
}
outgoingQueue.add(msg);
outgoingQueues.put(outgoingIndex, outgoingQueue);
}
@Override
public ConcurrentLinkedQueue<BSPMessage> removeIncomedQueue(String dstVertexID) {
ConcurrentLinkedQueue<BSPMessage> incomedQueue = null;
if(incomedQueues.containsKey(dstVertexID)){
incomedQueue = incomedQueues.getDupilcates(dstVertexID);
incomedQueues.delete(dstVertexID);
}
else{
incomedQueue = new ConcurrentLinkedQueue<BSPMessage>();
}
return incomedQueue;
}
@Override
public int getIncomingQueueSize(String dstVertexID) {
if (incomingQueues.containsKey(dstVertexID)) {
return incomingQueues.getkeyFrequnce(dstVertexID);
} else {
return 0;
}
}
@Override
public ConcurrentLinkedQueue<BSPMessage> removeIncomingQueue(String dstVertexID) {
ConcurrentLinkedQueue<BSPMessage> incomingQueue = null;
if(incomingQueues.containsKey(dstVertexID)){
incomingQueue = incomingQueues.getDupilcates(dstVertexID);
}
else{
incomingQueue = new ConcurrentLinkedQueue<BSPMessage>();
}
return incomingQueue;
}
@Override
public ConcurrentLinkedQueue<BSPMessage> removeOutgoingQueue(String index) {
ConcurrentLinkedQueue<BSPMessage> outgoingQueue = outgoingQueues.remove(index);
if (outgoingQueue == null) {
outgoingQueue = new ConcurrentLinkedQueue<BSPMessage>();
}
return outgoingQueue;
}
@Override
public int getOutgoingQueueSize(String index) {
if (outgoingQueues.containsKey(index)) {
return outgoingQueues.get(index).size();
} else {
return 0;
}
}
private void deleteFile(String filepath){
File f = new File(filepath);
if (f.exists() && f.isDirectory()) {
if (f.listFiles().length==0) {
f.delete();
} else {
File delFile[] = f.listFiles();
int i = f.listFiles().length;
for (int j = 0; j < i; j ++) {
if (delFile[j].isDirectory()) {
deleteFile(delFile[j].getAbsolutePath());
}
delFile[j].delete();
}
}
}
}
@Override
public void showMemoryInfo() {
}
@Override
public String getNextOutgoingQueueIndex() {
String nextIndex = null;
synchronized(this.outgoingQueues) {
int size = this.outgoingQueues.size();
if (size == 0) {
return null;
}
if (this.nextOutgoingQueueCount >= size) {
this.nextOutgoingQueueCount = 1;
}
Entry<String, ConcurrentLinkedQueue<BSPMessage>> entry = null;
Iterator<Entry<String, ConcurrentLinkedQueue<BSPMessage>>> it = this.outgoingQueues.entrySet().iterator();
for (int i = 0; i < this.nextOutgoingQueueCount; i ++) {
entry = it.next();
nextIndex = entry.getKey();
}
this.nextOutgoingQueueCount ++;
}
return nextIndex;
}
}