Esempio n. 1
0
/*
 *  1 - if request is not submitted since local server can handle it
 *  0 - if request is submitted successfully
 * -1 - in case of error submitting request
 *        - out of memory
 *        - invalid arguments
 *        - other system limitations
 */
int clusterMapGet(clusterMap_t clusterMap, void* luaContext,  void* keyContext, char* server, char* key ) {
	clusterMapImpl_t* pCM         = CLUSTER_MAP(clusterMap);
	request_t*        newRequest  = 0;
	externalServer_t* pEServer    = 0;
	int               returnValue = 0;

	IfTrue(pCM && server && key &&  luaContext, ERR, "Null argument found");
	newRequest = createRequest(key, luaContext, keyContext);
	IfTrue(newRequest, ERR, "Error allocting memory for new request");

	pEServer = mapGetElement(pCM->serverMap, server);
	if (!pEServer) {
		pEServer = externalServerCreate(server, pCM);
		IfTrue(pEServer, ERR, "Error creating server entry for server %s", server);
		mapPutElement(pCM->serverMap, server, pEServer);
	}
	externalServerSubmit(pEServer, newRequest);
	goto OnSuccess;
OnError:
	if (newRequest) {
		deleteRequest(newRequest);
		newRequest = 0;
	}
	returnValue = -1;
OnSuccess:
	return returnValue;
}
Esempio n. 2
0
void Parse::emit_guard_for_new(ciInstanceKlass* klass) {
  // Emit guarded new
  //   if (klass->_init_thread != current_thread ||
  //       klass->_init_state != being_initialized)
  //      uncommon_trap
  Node* cur_thread = _gvn.transform( new (C, 1) ThreadLocalNode() );
  Node* merge = new (C, 3) RegionNode(3);
  _gvn.set_type(merge, Type::CONTROL);
  Node* kls = makecon(TypeKlassPtr::make(klass));

  Node* init_thread_offset = _gvn.MakeConX(instanceKlass::init_thread_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes());
  Node* adr_node = basic_plus_adr(kls, kls, init_thread_offset);
  Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS);
  Node *tst   = Bool( CmpP( init_thread, cur_thread), BoolTest::eq);
  IfNode* iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
  set_control(IfTrue(iff));
  merge->set_req(1, IfFalse(iff));

  Node* init_state_offset = _gvn.MakeConX(instanceKlass::init_state_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes());
  adr_node = basic_plus_adr(kls, kls, init_state_offset);
  Node* init_state = make_load(NULL, adr_node, TypeInt::INT, T_INT);
  Node* being_init = _gvn.intcon(instanceKlass::being_initialized);
  tst   = Bool( CmpI( init_state, being_init), BoolTest::eq);
  iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
  set_control(IfTrue(iff));
  merge->set_req(2, IfFalse(iff));

  PreserveJVMState pjvms(this);
  record_for_igvn(merge);
  set_control(merge);

  uncommon_trap(Deoptimization::Reason_uninitialized,
                Deoptimization::Action_reinterpret,
                klass);
}
Esempio n. 3
0
/* returns -1 on error, 1 if more input is required, 0 when parse is complete */
int responseParserParse(responseParser_t parser, dataStream_t dataStream) {
	responseParserImpl_t* pParser = RESPONSE_PARSER(parser);
	char** tokens = 0;
	int    ntokens = 0, endOfLine = 0, parseResult = 0, returnValue = 0;

	IfTrue(pParser, ERR, "Null Parser Object");

	if (pParser->state == parse_first) {
		endOfLine = dataStreamFindEndOfLine(dataStream);
		if (endOfLine <= 0) {
			returnValue = 1;
			goto OnSuccess;
		}
		pParser->endOfLine = endOfLine;
		tokens = tokenizeFirstLine(pParser->fallocator, dataStream, endOfLine, &ntokens);
		IfTrue(tokens, DEBUG, "Error getting tokens");
		parseResult = parseFirstLineResponse(pParser->fallocator, pParser, tokens, ntokens);
		if (parseResult < 0) {
			LOG(INFO, "parsing error %d\n", parseResult);
			goto OnError;
		}
		if (pParser->endOfResponse) {
			LOG(DEBUG, "endOfResponse %d", pParser->endOfResponse);
			pParser->endOfValue = endOfLine+2;
			goto OnSuccess;
		}

		pParser->state      = parse_data;
		pParser->endOfValue = endOfLine + 2 + pParser->valueLength + 2;
	}

	if (pParser->state == parse_data) {
		if (dataStreamGetSize(dataStream) < pParser->endOfValue) {
			returnValue = 1;
			goto OnSuccess;
		}
		pParser->value = dataStreamSubStream(pParser->fallocator, dataStream,
								(pParser->endOfLine+2), pParser->valueLength);
		IfTrue(pParser->value, INFO, "Error creating data stream");
	}
	goto OnSuccess;
OnError:
	returnValue = -1;
OnSuccess:
	if (pParser) {
		cleanupTokens(pParser->fallocator, tokens, ntokens);
		tokens = 0;
	}
	return returnValue;
}
Esempio n. 4
0
/**
 * creates a request object which encapsulates all the information
 * necessary for making a request
 */
static request_t*  createRequest(char* virtualKey, void* luaContext, void* keyContext) {
	request_t* pRequest = ALLOCATE_1(request_t);

	IfTrue(pRequest, ERR, "Error allocating memory");
	pRequest->key        = strdup(virtualKey);
	IfTrue(pRequest->key, ERR, "Error copying key");
	pRequest->luaContext = luaContext;
	pRequest->keyContext = keyContext;
	goto OnSuccess;
OnError:
	if (pRequest) {
		deleteRequest(pRequest);
		pRequest = 0;
	}
OnSuccess:
	return pRequest;
}
Esempio n. 5
0
/* choosing a default because otherwise everyone has to
 * choose and ensure that it is same all over, which
 * could be a pain.
 * Bigger todo is to have some way to specify weightage
 * with the servers.
 */
consistent_t consistentCreate(char* serverNames) {
	consistentImpl_t* pC = ALLOCATE_1(consistentImpl_t);

	IfTrue(pC, ERR, "Error allocating memory");

	pC->spread    = SPREAD;

	IfTrue( 0 == parseAndSetServerNames(pC, serverNames), ERR, "Error setting server names");
	IfTrue( 0 == calculatePoints(pC), ERR, "Error calculating points");

	goto OnSuccess;
OnError:
	consistentDelete(pC);
	pC = 0;
OnSuccess:
    return pC;
}
Esempio n. 6
0
static connectionContext_t* connectionContextCreate(connection_t conn, void* pServer) {
	connectionContext_t* pContext = ALLOCATE_1(connectionContext_t);

	IfTrue(conn, ERR, "Null Connection");
	IfTrue(pContext, ERR, "Error allocating memory");

	pContext->readStream = dataStreamCreate();
	IfTrue(pContext->readStream, WARN, "Error creating read stream");
	pContext->writeStream = dataStreamCreate();
	IfTrue(pContext->writeStream, WARN, "Error creating write stream");
	pContext->fallocator = fallocatorCreate();
	IfTrue(pContext->fallocator, WARN, "Error creating fallocator");
	pContext->parser = responseParserCreate(pContext->fallocator);
	IfTrue(pContext->parser, WARN, "Error creating parser");
	pContext->currentRequests = listCreate(OFFSET(request_t, pNext),
			                               OFFSET(request_t, pPrev));
	IfTrue(pContext->currentRequests, WARN, "Error creating request list");
	pContext->connection      = conn;
	pContext->pExternalServer = pServer;
	goto OnSuccess;
OnError:
	if (pContext) {
		connectionContextDelete(pContext, 0);
		pContext = 0;
	}
OnSuccess:
	return pContext;
}
Esempio n. 7
0
static externalServer_t* externalServerCreate(char* serverName, clusterMapImpl_t* pCM) {
	externalServer_t* pServer = ALLOCATE_1(externalServer_t);
	char* serverNameCopy      = 0;
	char* ip                  = 0;
	char* port                = 0;

	IfTrue(pServer, ERR, "Error allocating memory");
	pServer->serverName = strdup(serverName);
	IfTrue(pServer->serverName, ERR, "Error allocating memory");

	serverNameCopy = strdup(pServer->serverName);
	IfTrue(serverNameCopy, ERR, "Error allocating memory");

	ip = strtok(serverNameCopy, ":");
	IfTrue(ip, ERR, "Error parsing serverName");
	pServer->serverIP = strdup(ip);
	IfTrue(ip, ERR, "Error copying server ip");
	port = strtok(0, ":");
	IfTrue(port, ERR, "Error parsing server port");
	pServer->serverPort = atoi(port);
	FREE(serverNameCopy);
	serverNameCopy = 0;

	pServer->activeConnections  = listCreate(OFFSET(connectionContext_t, pNext),
								             OFFSET(connectionContext_t, pPrev));
	IfTrue(pServer->activeConnections, ERR, "Error allocating memory");
	pServer->freeConnections    = listCreate(OFFSET(connectionContext_t, pNext),
								     	     OFFSET(connectionContext_t, pPrev));
	IfTrue(pServer->freeConnections, ERR, "Error allocating memory");
	pServer->unassignedRequests = listCreate(OFFSET(request_t, pNext),
											 OFFSET(request_t, pPrev));
	IfTrue(pServer->unassignedRequests, ERR, "Error allocating memory");
	pServer->pClusterMap = pCM;
	goto OnSuccess;
OnError:
	if (serverNameCopy) {
		FREE(serverNameCopy);
	}
	if (pServer) {
		externalServerDelete(pServer);
		pServer = 0;
	}
OnSuccess:
	return pServer;
}
Esempio n. 8
0
/**
 * VALUE key flags datalength\r\n
 * <DATA>\r\n
 * END\r\n
 */
static int parseFirstLineResponse(fallocator_t fallocator, responseParserImpl_t* pParser, char** tokens,
		int ntokens) {
	int returnValue = 0;

	if (0 == strcmp(tokens[0], "END")) {
		pParser->endOfResponse = 1;
		goto OnSuccess;
	}
	if (0 == strcmp(tokens[0], "VALUE")) {
		pParser->key = tokens[1];
		tokens[1] = 0;

		IfTrue(safe_strtoul(tokens[2], &pParser->flags), INFO, "Error parsing flags");
		IfTrue(safe_strtoul(tokens[3], &pParser->valueLength), INFO, "Error parsing value length");
	}
	goto OnSuccess;
OnError:
	returnValue = -1;
OnSuccess:
	LOG(DEBUG, "endOfResponse %d", pParser->endOfResponse);
	return returnValue;
}
Esempio n. 9
0
static int calculatePoints(consistentImpl_t* pC) {
	char key[MAX_SERVER_NAME_SIZE];
	int length       = 0, returnValue = 0;
	int requiredSize = pC->spread * pC->serverCount;

	if (pC->pointsCount != requiredSize) {
		if (pC->points) {
			free(pC->points);
			pC->points      = 0;
			pC->pointsCount = 0;
		}
		pC->points = calloc(requiredSize, sizeof(point_t));
		IfTrue(pC->points, ERR, "Error allocating memory for points");
		pC->pointsCount = requiredSize;
	}

	for (int i = 0; i < pC->serverCount; i++) {
		for (int j = 0; j < pC->spread; j++) {
			memset(key, 0 , MAX_SERVER_NAME_SIZE);
			length = snprintf(key, MAX_SERVER_NAME_SIZE, "%s-%d", pC->servers[i].serverName, j);
			IfTrue(length < MAX_SERVER_NAME_SIZE, ERR, "server names to big");
			pC->points[(i*pC->spread)+j].hashPoint   = hashcode(pC, key, length);
			pC->points[(i*pC->spread)+j].serverIndex = i;
		}
	}
	qsort(pC->points, pC->pointsCount, sizeof(point_t), pointsCompare);

	goto OnSuccess;
OnError:
	if (pC->points) {
		free(pC->points);
		pC->points      = 0;
		pC->pointsCount = 0;
	}
	returnValue = -1;
OnSuccess:
	return returnValue;
}
Esempio n. 10
0
static int parseAndSetServerNames(consistentImpl_t* pC, char* serverNames) {
	char*      serverNamesCopy = 0;
	server_t*  array           = 0;
	int        size            = MIN_SERVER_NAMES_SIZE;
    int        count           = 0;
    char*      token           = 0;
    int        returnValue     = 0;

    IfTrue(pC, ERR, "Null consistent pointer");
    IfTrue(serverNames, ERR, "Null server names");
    serverNamesCopy = strdup(serverNames);
    IfTrue(serverNamesCopy, ERR,  "Error copying server names");

    array = calloc(size, sizeof(char*));
    IfTrue(array, ERR,  "Error allocating memory");

    token = strtok(serverNamesCopy, DELIM);

    while (token) {
    	array[count].serverName = strdup(token);
    	IfTrue(array[count].serverName, ERR,  "Error allocating memory");
    	array[count].available = 1;
    	count++;
    	if (count == size) {
    		server_t* newArray = realloc(array, sizeof(server_t) * size * 2);
    		IfTrue(newArray, ERR,  "Error allocating memory");
    		array = newArray;
    		size  = size * 2;
    	}
    	token = strtok(NULL, DELIM);
    }
    freeServers(pC);
    pC->servers     = array;
    pC->serverCount = count;
    goto OnSuccess;
OnError:
	if (array) {
		for (int i = 0; i < count; i++) {
			if (array[i].serverName) {
				free(array[i].serverName);
				array[i].serverName = 0;
			}
		}
		free(array);
		array = 0;
	}
	returnValue = -1;
OnSuccess:
	if (serverNamesCopy) {
		free(serverNamesCopy);
		serverNamesCopy = 0;
	}
	return returnValue;
}
Esempio n. 11
0
static int externalServerSubmit(externalServer_t* pServer, request_t* pRequest) {
	int                  returnValue   = 0;
	connectionContext_t* pCContext     = 0;
	connection_t         newConnection = 0;

	listAddLast(pServer->unassignedRequests, pRequest);
	pCContext = listRemoveFirst(pServer->freeConnections);

	if (pCContext) {
		connectionWaitCancel(pCContext->connection, getGlobalEventBase());
	}

	if (!pCContext) {
		//check if we have reached max concurrent connections limit
		// if not, create a new connection
		if (listGetSize(pServer->activeConnections) < MAX_CONCURRENT_CONNECTIONS) {
			LOG(DEBUG, "creating new external connection");
			newConnection = connectionClientCreate(pServer->serverIP,
												pServer->serverPort,
												createConnectionHandler());
			IfTrue(newConnection, ERR, "Error creating new connection to %s", pServer->serverName);
			//got a new connection
			pCContext = connectionContextCreate(newConnection, pServer);
			IfTrue(pCContext, ERR, "Error allocting memory for connection context");
			connectionSetContext(newConnection, pCContext);
			newConnection = 0;

			int err = connectionConnect(pCContext->connection);
			IfTrue(err >= 0, ERR, "connect failed");

			if (err == 1) {
				LOG(DEBUG, "waiting for connect to complete");
				pCContext->status = status_connecting;
				connectionWaitForConnect(pCContext->connection, getGlobalEventBase());
				goto OnSuccess;
			}
		}else {
			//if we have reached max connection limit, we will let the request rest
			//in the queue. Whenever one of the current connections get free, we will
			//use that to send the request.
			returnValue = 1;
			goto OnSuccess;
		}
	}

	if (pCContext) {
		pCContext->status = status_active;
		connectionSubmitRequests(pServer, pCContext);
	}
	goto OnSuccess;
OnError:
	if (newConnection) {
		connectionClose(newConnection);
	}
	if (pCContext) {
		connectionContextDelete(pCContext, 0);
	}
	returnValue = 1;
OnSuccess:
	return returnValue;
}
Esempio n. 12
0
static void readAvailableImpl(connection_t connection){
	connectionContext_t* pCContext    = connectionGetContext(connection);
	u_int32_t            bytesRead   = 0;
	int                  returnValue = 0;

	LOG(DEBUG, "got something to read on socket");

	//if it is one of the pooled connections
	if (pCContext->status == status_pooled) {
		LOG(DEBUG, "socket was pooled..closing on read");
		//socket is closed
		externalServer_t* pServer = pCContext->pExternalServer;
		listRemove(pServer->freeConnections, pCContext);
		connectionContextDelete(pCContext, 0);
		goto OnSuccess;
	}

	if (pCContext->status == status_waiting_read) {
		pCContext->status = status_active;
	}else {
		LOG(ERR, "Invalid connection state");
		goto OnError;
	}

	returnValue = connectionRead(pCContext->connection, pCContext->fallocator,
			                   pCContext->readStream, 8 * 1024 , &bytesRead);
	LOG(DEBUG, "connection read status %d bytesRead %d", returnValue, bytesRead);
	IfTrue(returnValue >= 0, INFO, "Socket closed");

doParseMore:

	returnValue = responseParserParse(pCContext->parser, pCContext->readStream);
	LOG(DEBUG, "response parser status %d", returnValue);
	IfTrue(returnValue >= 0, INFO, "Parsing Error %d", returnValue);

	if (returnValue == 1) {
		LOG(DEBUG, "need to wait for read");
		pCContext->status = status_waiting_read;
		connectionWaitForRead(pCContext->connection, getGlobalEventBase());
		goto OnSuccess;
	}

	char*         key   = 0;
	dataStream_t  value = 0;
	u_int32_t     flags = 0;

	returnValue = responseParserGetResponse(pCContext->parser, pCContext->readStream,
			                                &key, &value, &flags);
	LOG(DEBUG, "got resposonse %d key %s", returnValue, key);

	if (returnValue == 0) {
		externalServer_t* pServer  = pCContext->pExternalServer;
		clusterMapImpl_t* pCM      = pServer->pClusterMap;
		request_t*        pRequest = 0;

tryNext:
	    pRequest = listRemoveFirst(pCContext->currentRequests);
	    if (pRequest) {
			if (0 == strcmp(pRequest->key, key)) {
				//we got the response for the key
				LOG(DEBUG, "giving callback for success result");
				pCM->resultHandler(pRequest->luaContext, pRequest->keyContext, 0, value);
				dataStreamDelete(value);
				value    = 0;
				fallocatorFree(pCContext->fallocator, key);
				key      = 0;
				deleteRequest(pRequest);
				pRequest = 0;
				goto doParseMore;
			}else {
				//this key is different from the key we expected
				//the request for current key failed, so notify
				LOG(DEBUG, "giving callback for fail result");

				pCM->resultHandler(pRequest->luaContext, pRequest->keyContext,  -1, NULL);
				deleteRequest(pRequest);
				pRequest = 0;
				//move on to the next key, may be its her response
				goto tryNext;
			}
	    }else {
	    	// no more request in the currentRequests list?
            // what this means is that we got a response for a key
	    	// which we didn't asked for...
	    	// that is strange.., some server issue..we can't do much
	    	dataStreamDelete(value);
	    	value = 0;
	        fallocatorFree(pCContext->fallocator, key);
	    	key   = 0;
	    	// now so just close this connection

	    	externalServer_t* pServer = pCContext->pExternalServer;
			listRemove(pServer->activeConnections, pCContext);
			connectionContextDelete(pCContext, 0);
			pCContext = 0;
	    }
	}else {
		LOG(DEBUG, "end of results from response parser");
		// we go END response from parser
		externalServer_t* pServer = pCContext->pExternalServer;
		clusterMapImpl_t* pCM      = pServer->pClusterMap;
		request_t*        pRequest = 0;
		//anything pending in the currentRequests..not found
		while ((pRequest = listRemoveLast(pCContext->currentRequests)) != 0) {
			//report error
			pCM->resultHandler(pRequest->luaContext, pRequest->keyContext, -1,  NULL);
			deleteRequest(pRequest);
		}
		// add this connections to free connections list
	    listRemove(pServer->activeConnections, pCContext);
	    connectionSubmitRequests(pServer, pCContext);
	}
	goto OnSuccess;
OnError:
	if (pCContext) {
		externalServer_t* pServer = pCContext->pExternalServer;
		listRemove(pServer->activeConnections, pCContext);
		connectionContextDelete(pCContext, 1);
		pCContext = 0;
	}
OnSuccess:
	return;
}
Esempio n. 13
0
static int parseFirstLineRequest(fallocator_t fallocator, requestParserImpl_t* pParser, char** tokens, int ntokens) {
	int returnValue = 0;

	if (ntokens >= 2 && (((strcmp(tokens[0], "get") == 0) && (pParser->pCommand->command
			= COMMAND_GET)) || ((strcmp(tokens[0], "bget") == 0)
			&& (pParser->pCommand->command = COMMAND_BGET)))) {

		if (ntokens > 2) {
			//copy the keys ...
			pParser->pCommand->multiGetKeys = fallocatorMalloc(fallocator, (ntokens-1) * sizeof(char*));
			IfTrue(pParser->pCommand->multiGetKeys, WARN, "Error allocating memory");
			pParser->pCommand->multiGetKeysCount = ntokens -1 ;
			for (int i = 1; i < ntokens; i++) {
				pParser->pCommand->multiGetKeys[i-1] = tokens[i];
				tokens[i] = 0;
			}
		}else {
			pParser->pCommand->key = tokens[1];
			pParser->pCommand->keySize = strlen(tokens[1]);
			tokens[1] = 0;
		}
	} else if ((ntokens == 5 || ntokens == 6) && ((strcmp(tokens[0], "add")
			== 0 && (pParser->pCommand->command = COMMAND_ADD)) || (strcmp(tokens[0],
			"set") == 0 && (pParser->pCommand->command = COMMAND_SET)) || (strcmp(
			tokens[0], "replace") == 0 && (pParser->pCommand->command = COMMAND_REPLACE))
			|| (strcmp(tokens[0], "prepend") == 0 && (pParser->pCommand->command
					= COMMAND_PREPEND)) || (strcmp(tokens[0], "append") == 0
			&& (pParser->pCommand->command = COMMAND_APPEND)))) {
		pParser->pCommand->key = tokens[1];
		pParser->pCommand->keySize = strlen(tokens[1]);
		tokens[1] = 0;
		IfTrue(safe_strtoul(tokens[2], &pParser->pCommand->flags), INFO, "Error parsing flags");
		IfTrue(safe_strtoul(tokens[3], &pParser->pCommand->expiryTime), INFO, "Error parsing expiry time ");
		IfTrue(safe_strtoul(tokens[4], &pParser->pCommand->dataLength), INFO, "Error parsing data length");

		if (tokens[5] != NULL) {
			if (strcmp(tokens[5], "noreply") == 0) {
				pParser->pCommand->noreply = 1;
			}
		}

	} else if ((ntokens == 6 || ntokens == 7)
			&& (strcmp(tokens[0], "cas") == 0)) {
		pParser->pCommand->command = COMMAND_CAS;

		pParser->pCommand->key = tokens[1];
		pParser->pCommand->keySize = strlen(tokens[1]);
		tokens[1] = 0;
		IfTrue(safe_strtoul(tokens[2], &pParser->pCommand->flags), INFO, "Error parsing flags");
		IfTrue(safe_strtoul(tokens[3], &pParser->pCommand->expiryTime), INFO, "Error parsing expiry time ");
		IfTrue(safe_strtoul(tokens[4], &pParser->pCommand->dataLength), INFO, "Error parsing data length");
		IfTrue(safe_strtoull(tokens[5], &pParser->pCommand->cas), INFO, "Error parsing cas id");

		if (tokens[6] != NULL) {
			if (strcmp(tokens[6], "noreply") == 0) {
				pParser->pCommand->noreply = 1;
			}
		}

	} else if ((ntokens == 3 || ntokens == 4) && (strcmp(tokens[0], "incr")
			== 0)) {
		pParser->pCommand->command = COMMAND_INCR;
		pParser->pCommand->key = tokens[1];
		pParser->pCommand->keySize = strlen(tokens[1]);
		tokens[1] = 0;

		IfTrue(safe_strtoull(tokens[2], &pParser->pCommand->delta), INFO, "Error parsing delta");
		if (tokens[3] != NULL) {
			if (strcmp(tokens[3], "noreply") == 0) {
				pParser->pCommand->noreply = 1;
			}
		}
	} else if (ntokens >= 2 && (strcmp(tokens[0], "gets") == 0)) {
		pParser->pCommand->command = COMMAND_GETS;
		pParser->pCommand->key = tokens[1];
		pParser->pCommand->keySize = strlen(tokens[1]);
		tokens[1] = 0;
		//TODO - only suport one key per get for now

	} else if ((ntokens == 4 || ntokens == 5) && (strcmp(tokens[0], "decr")
			== 0)) {
		pParser->pCommand->command = COMMAND_DECR;
		pParser->pCommand->key = tokens[1];
		pParser->pCommand->keySize = strlen(tokens[1]);
		tokens[1] = 0;

		IfTrue(safe_strtoull(tokens[2], &pParser->pCommand->delta), INFO, "Error parsing delta");
		if (tokens[3] != NULL) {
			if (strcmp(tokens[3], "noreply") == 0) {
				pParser->pCommand->noreply = 1;
			}
		}
	} else if (ntokens >= 2 && ntokens <= 4 && (strcmp(tokens[0], "delete")
			== 0)) {
		pParser->pCommand->command = COMMAND_DELETE;
		pParser->pCommand->key = tokens[1];
		pParser->pCommand->keySize = strlen(tokens[1]);
		tokens[1] = 0;
		if (tokens[2] != NULL) {
			if (strcmp(tokens[2], "noreply") == 0) {
				pParser->pCommand->noreply = 1;
			}
		}
	} else if (ntokens >= 2 && (strcmp(tokens[0], "stats") == 0)) {
		pParser->pCommand->command = COMMAND_STATS;
		//TODO - later
	} else if (ntokens >= 1 && ntokens <= 2 && (strcmp(tokens[0], "flush_all")
			== 0)) {
		pParser->pCommand->command = COMMAND_FLUSH_ALL;
		//TODO - later
	} else if (ntokens == 1 && (strcmp(tokens[0], "version") == 0)) {
		pParser->pCommand->command = COMMAND_VERSION;
		//TODO - later
	} else if (ntokens == 1 && (strcmp(tokens[0], "quit") == 0)) {
		pParser->pCommand->command = COMMAND_QUIT;
		//TODO - later
	} else if ((ntokens == 2 || ntokens == 3)
			&& (strcmp(tokens[0], "verbosity") == 0)) {
		pParser->pCommand->command = COMMAND_VERBOSITY;
		IfTrue(safe_strtoul(tokens[2], &pParser->pCommand->flags), INFO,
				"Error parsing verosity level");
	} else {
		//this is error
	}
	goto OnSuccess;
OnError:
	returnValue = -1;
OnSuccess:
	return returnValue;
}