Example #1
0
Req*
removereq(Reqpool *pool, ulong tag)
{
    if(chatty9p > 1)
        fprint(2, "removereq %lud\n", tag);
    return deletekey(pool->map, tag);
}
// Handle the delete message coming at its correct destinations
void MP2Node::processDelete(Message incoming_msg) {
    // Calls the server local function to delete key from its local hash table.
    bool success_status = deletekey(incoming_msg.key);
    int _trans_id = incoming_msg.transID; // get trans_id from the incoming message
    Address to_addr(incoming_msg.fromAddr); // get the coordinator address from where this message came

    if (_trans_id < 0)//if stablization came with trans_id = -1. This is special type of message that comes when ring repair work is going on. So, don't send its reply
        return;

    Message *msg = new Message(_trans_id, getMemberNode()->addr, REPLY, success_status); // send reply message back to the coordinator
    emulNet->ENsend(&getMemberNode()->addr, &to_addr, msg->toString());

    // if the local delete operation returns success then log server success otherwise log failure.
    if (success_status)
        log->logDeleteSuccess(&getMemberNode()->addr, false, _trans_id, incoming_msg.key);
    else
        log->logDeleteFail(&getMemberNode()->addr, false, _trans_id, incoming_msg.key);

    // free the message variable
    free(msg);
}
Example #3
0
/**
 * FUNCTION NAME: checkMessages
 *
 * DESCRIPTION: This function is the message handler of this node.
 * 				This function does the following:
 * 				1) Pops messages from the queue
 * 				2) Handles the messages according to message types
 */
void MP2Node::checkMessages() {
	/*
	 * Implement this. Parts of it are already implemented
	 */
	char * data;
	int size;

	/*
	 * Declare your local variables here
	 */

	// dequeue all messages and handle them
	while ( !memberNode->mp2q.empty() ) {
		/*
		 * Pop a message from the queue
		 */
		data = (char *)memberNode->mp2q.front().elt;
		size = memberNode->mp2q.front().size;
		memberNode->mp2q.pop();

		string msg_string(data, data + size);

		/*
		 * Handle the message types here
		 */
		Message recv_msg = Message(msg_string);
		bool success;
		switch (recv_msg.type) {
			case CREATE:
			{
				success = createKeyValue(recv_msg.key, recv_msg.value, recv_msg.replica);
				if (success)
					log->logCreateSuccess(&memberNode->addr, false, recv_msg.transID, recv_msg.key, recv_msg.value);
				else
					log->logCreateFail(&memberNode->addr, false, recv_msg.transID, recv_msg.key, recv_msg.value);
				//send reply
				Message send_msg = Message(recv_msg.transID, memberNode->addr, REPLY, success);
				emulNet->ENsend(&memberNode->addr, &recv_msg.fromAddr, send_msg.toString());
				break;
			}
			case UPDATE:
			{
				success = updateKeyValue(recv_msg.key, recv_msg.value, recv_msg.replica);
				if (success)
					log->logUpdateSuccess(&memberNode->addr, false, recv_msg.transID, recv_msg.key, recv_msg.value);
				else
					log->logUpdateFail(&memberNode->addr, false, recv_msg.transID, recv_msg.key, recv_msg.value);
				//send reply
				Message send_msg = Message(recv_msg.transID, memberNode->addr, REPLY, success);
				emulNet->ENsend(&memberNode->addr, &recv_msg.fromAddr, send_msg.toString());
				break;
			}
			case READ:
			{
				string ret = readKey(recv_msg.key);
				if ("" != ret)
					log->logReadSuccess(&memberNode->addr, false, recv_msg.transID, recv_msg.key, ret);
				else
					log->logReadFail(&memberNode->addr, false, recv_msg.transID, recv_msg.key);
				//send read reply
				Message send_msg = Message(recv_msg.transID, memberNode->addr, ret);
				emulNet->ENsend(&memberNode->addr, &recv_msg.fromAddr, send_msg.toString());
				break;
			}
			case DELETE:
			{
				success = deletekey(recv_msg.key);
				if (success)
					log->logDeleteSuccess(&memberNode->addr, false, recv_msg.transID, recv_msg.key);
				else
					log->logDeleteFail(&memberNode->addr, false, recv_msg.transID, recv_msg.key);
				//send reply
				Message send_msg = Message(recv_msg.transID, memberNode->addr, REPLY, success);
				emulNet->ENsend(&memberNode->addr, &recv_msg.fromAddr, send_msg.toString());
				break;
			}
			case REPLY:
			{
				for (list<Transaction>::iterator it = buff.begin(); it != buff.end(); ++it) {
					if (it->transID_ == recv_msg.transID) {
						if (it->isStart())
							it->startCount();
						if (recv_msg.success) {
							it->increCount();
						}
						break;
					}
				}
				break;
			}
			case READREPLY:
			{
				for (list<ReadTransaction>::iterator it = buffRead.begin(); it != buffRead.end(); ++it) {
					if (it->transID_ == recv_msg.transID) {
						if (it->isStart()) {
							it->startCount();
						}
						if (recv_msg.value != "") {
							it->increCount();
							it->pushValue(recv_msg.value);
							break;
						}
					}
				}
				break;
			}
		}

	}
	/*
	 * This function should also ensure all READ and UPDATE operation
	 * get QUORUM replies
	 */
	for (list<ReadTransaction>::iterator it = buffRead.begin(); it != buffRead.end(); ) {
		if (it->count_ == -1) {
			it++;
		} else if (it->count_ >= QUORUM) {
			//case READ
			int max = 0;
			string ret;
			for (auto i = it->values_.begin(); i != it->values_.end(); ++i) {
				if (i->second > max)
					ret = i->first;
				//TODO for two euqal max
				//else if (i->second == max) {
				//	log->logReadFail(&memberNode->addr, true, it->transID_, it->key_);
				//}
			}
			log->logReadSuccess(&memberNode->addr, true, it->transID_, it->key_, ret);
			it = buffRead.erase(it);
		} else { //if (it->count_ < QUORUM)
			//case READ
			log->logReadFail(&memberNode->addr, true, it->transID_, it->key_);
			it = buffRead.erase(it);
		}
	}

	for (list<Transaction>::iterator it = buff.begin(); it != buff.end(); ) {
		if (it->count_ == -1) {
			it++;
		} else if (it->count_ >= QUORUM) {
			switch (it->type_) {
				case CREATE:
					log->logCreateSuccess(&memberNode->addr, true, it->transID_, it->key_, it->value_);
					break;
				case UPDATE:
					log->logUpdateSuccess(&memberNode->addr, true, it->transID_, it->key_, it->value_);
					break;
				case DELETE:
					log->logDeleteSuccess(&memberNode->addr, true, it->transID_, it->key_);
					break;
				default:
					//error
					break;
			}
			it = buff.erase(it);
		} else { //if (it->count_ < QUORUM)
			switch (it->type_) {
				case CREATE:
					log->logCreateFail(&memberNode->addr, true, it->transID_, it->key_, it->value_);
					break;
				case UPDATE:
					log->logUpdateFail(&memberNode->addr, true, it->transID_, it->key_, it->value_);
					break;
				case DELETE:
					log->logDeleteFail(&memberNode->addr, true, it->transID_, it->key_);
					break;
				default:
					//error
					break;
			}
			it = buff.erase(it);
		}
	}
}
int main(int argc, char *argv[])
{
	int opt;
	char* appName = NULL;
	char* resourceID = NULL;
	char* payloadBuffer = NULL;
	char* fileName = NULL;
	unsigned char* writeBuffer = NULL;
	eOperationMode opMode = modeInvalid;
	unsigned int user_no = 0, seat_no = 0;
	unsigned int ldbid = 0xFF;    // default value
	unsigned int doHexdump = 0;

	printf("\n");
   /// debug log and trace (DLT) setup
   DLT_REGISTER_APP("Ptool","persistence client library tools");


	while ((opt = getopt(argc, argv, "hVo:a:u:s:r:-l:p:f:H")) != -1)
	{
		switch (opt)
		{
		   case 'o':      // option
		      if(strcmp(optarg, "readkey")  == 0)
            {
		         opMode = modeReadKey;
            }
		      else if(strcmp(optarg, "writekey")  == 0)
            {
		         opMode = modeWriteKey;
            }
		      else if(strcmp(optarg, "deletekey")  == 0)
            {
		         opMode = modeDeleteKey;
            }
		      else if(strcmp(optarg, "getkeysize")  == 0)
            {
		         opMode = modeGetKeySize;
            }
		      else
		      {
		         printf("Unsupported Unsupported mode: %s\"\n\"", optarg);
		         printSynopsis();
	            exit(EXIT_FAILURE);
		      }
		      break;
		   case 'a':   // application name
		   {
		      size_t len = strlen(optarg);
            appName = malloc(len + 1);
            if(appName != NULL)
            {
               memset(appName, 0, len + 1);
               strncpy(appName, optarg, len);
            }
		   }
		      break;
		   case 'r':   // resource ID
         {
            size_t len = strlen(optarg);
            resourceID = malloc(len + 1);
            if(resourceID != NULL)
            {
               memset(resourceID, 0, len + 1);
               strncpy(resourceID, optarg, len);
            }
         }
            break;
         case 'p':   // payload to write
         {
            size_t len = strlen(optarg);
            payloadBuffer = malloc(len + 1);
            if(payloadBuffer != NULL)
            {
               memset(payloadBuffer, 0, len + 1);
               strncpy(payloadBuffer, optarg, len);
            }
         }
            break;
         case 'f':   // filename to read data from, write data to
         {
            size_t len = strlen(optarg);
            fileName = malloc(len + 1);
            if(fileName != NULL)
            {
               memset(fileName, 0, len + 1);
               strncpy(fileName, optarg, len);
            }
         }
            break;
		   case 'u':   // user number
		      user_no = (unsigned int)atoi(optarg);
		      break;
		   case 's':   // seat number
            seat_no = (unsigned int)atoi(optarg);
            break;
		   case 'l':
		      ldbid = (unsigned int)strtol(optarg, NULL, 16);
		      break;
		   case 'H':   // hexdump of data
		      doHexdump = 1;
		      break;
	   	case 'h':   // help
	   	   printSynopsis();
	         break;
	   	case 'v':   // version
	   		printf("Version: %s\n", PCLT_VERSION);
	         break;
	   	default: /* '?' */
	      	printSynopsis();
	         exit(EXIT_FAILURE);
	         break;
		}
   }


	if(appName != NULL && resourceID != NULL)
	{
	   printf("Application name: %s\n", appName);

	   int shutdownReg = PCL_SHUTDOWN_TYPE_NONE;
	   (void)pclInitLibrary(appName, shutdownReg);

      switch(opMode)
      {
         case modeReadKey:
         {
            unsigned char* buffer = NULL;
            int keysize = pclKeyGetSize(ldbid, resourceID, user_no, seat_no);

            if(keysize > 0)
            {
               buffer = malloc((size_t)keysize + 1);
               if(buffer != NULL)
               {
                  memset(buffer, 0, (size_t)(keysize + 1));
                  readKey(resourceID, user_no, seat_no, ldbid, doHexdump, buffer, keysize);

                  if(fileName != NULL)
                     (void)writeDataToFile(fileName, buffer, keysize);

                  free(buffer);
               }
            }
            else
            {
               printf("readkey: key is empty: %d\n", keysize);
            }
            break;
         }
         case modeWriteKey:
            if(fileName != NULL)    // if filename is available, read data from file
            {
               writeBuffer = readDataFromFile(fileName);
            }
            else
            {
               writeBuffer = (unsigned char*)payloadBuffer;    // use data from payload parameter
            }

            if(writeBuffer != NULL)
            {
               writeKey(resourceID, user_no, seat_no, ldbid, writeBuffer, doHexdump);
            }
            else
            {
               printf("No Data to write to key\n");
            }
            break;
         case modeDeleteKey:
            deletekey(resourceID, user_no, seat_no, ldbid);
            break;
         case modeGetKeySize:
            getkeysize(resourceID, user_no, seat_no, ldbid);
            break;
         default:
            printSynopsis();
            break;
      }

      if(appName != NULL)
         free(appName);

      if(resourceID != NULL)
         free(resourceID);

      if(writeBuffer != NULL)
         free(writeBuffer);

      if(fileName != NULL)
         free(fileName);


      pclLifecycleSet(PCL_SHUTDOWN);

      pclDeinitLibrary();
	}
	else
	{
	   printf("Invalid application name or resourceID\n");
	   exit(EXIT_FAILURE);
	}

   // unregister debug log and trace
   DLT_UNREGISTER_APP();
   dlt_free();

   printf("\n");

   return 0;
}