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); }
/** * 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; }