bool Table::Get(Transaction* tx, const char* key, uint64_t& value) { ByteArray<32> ba; unsigned nread; if (!Get(tx, key, ba)) return false; value = strntouint64(ba.buffer, ba.length, &nread); if (nread != ba.length) return false; return true; }
int Keyspace_DirtyListKeyValuesStr(ClientObj client_, const std::string& prefix_, const std::string& startKey_, const std::string& count_, bool next_, bool forward_) { Keyspace::Client* client = (Keyspace::Client *) client_; ByteString prefix(prefix_.length(), prefix_.length(), prefix_.c_str()); ByteString startKey(startKey_.length(), startKey_.length(), startKey_.c_str()); unsigned read; uint64_t count; count = strntouint64(count_.c_str(), count_.length(), &read); if (read != count_.length()) return KEYSPACE_API_ERROR; return client->DirtyListKeyValues(prefix, startKey, count, next_, forward_); }
uint64_t ReplicatedKeyspaceDB::GetExpiryTime(ByteString key) { uint64_t expiryTime; ByteString userValue; unsigned nread; WriteExpiryKey(kdata, key); if (table->Get(RLOG->GetTransaction(), kdata, rdata)) { Log_Trace("read %.*s => %.*s", kdata.length, kdata.buffer, rdata.length, rdata.buffer); // the key has an expiry expiryTime = strntouint64(rdata.buffer, rdata.length, &nread); if (nread < 1) ASSERT_FAIL(); return expiryTime; } else return 0; }
bool SingleKeyspaceDB::Add(KeyspaceOp* op) { // Log_Trace(); bool isWrite; int64_t num; unsigned nread; uint64_t storedPaxosID, storedCommandID, expiryTime; ByteString userValue; isWrite = op->IsWrite(); if (isWrite && !transaction.IsActive()) { transaction.Set(table); transaction.Begin(); } op->status = true; if (op->IsWrite() && writePaxosID) { if (table->Set(&transaction, "@@paxosID", "1")) writePaxosID = false; } if (op->IsGet()) { op->value.Allocate(KEYSPACE_VAL_SIZE); op->status &= table->Get(NULL, op->key, vdata); if (op->status) { ReadValue(vdata, storedPaxosID, storedCommandID, userValue); op->value.Set(userValue); } op->service->OnComplete(op); } else if (op->IsList() || op->IsCount()) { AsyncListVisitor *alv = new AsyncListVisitor(op); MultiDatabaseOp* mdbop = new AsyncMultiDatabaseOp(); mdbop->Visit(table, *alv); dbReader.Add(mdbop); } else if (op->type == KeyspaceOp::SET) { WriteValue(vdata, 1, 0, op->value); op->status &= table->Set(&transaction, op->key, vdata); op->service->OnComplete(op); } else if (op->type == KeyspaceOp::TEST_AND_SET) { op->status &= table->Get(&transaction, op->key, vdata); if (op->status) { ReadValue(vdata, storedPaxosID, storedCommandID, userValue); if (userValue == op->test) { WriteValue(vdata, 1, 0, op->value); op->status &= table->Set(&transaction, op->key, vdata); } else op->value.Set(userValue); } op->service->OnComplete(op); } else if (op->type == KeyspaceOp::ADD) { // read number: op->status = table->Get(&transaction, op->key, vdata); if (op->status) { ReadValue(vdata, storedPaxosID, storedCommandID, userValue); // parse number: num = strntoint64(userValue.buffer, userValue.length, &nread); if (nread == (unsigned) userValue.length) { num = num + op->num; // print number: vdata.length = snwritef(vdata.buffer, vdata.size, "1:0:%I", num); // write number: op->status &= table->Set(&transaction, op->key, vdata); // returned to the user: vdata.length = snwritef(vdata.buffer, vdata.size, "%I", num); op->value.Allocate(vdata.length); op->value.Set(vdata); } else op->status = false; } op->service->OnComplete(op); } else if (op->type == KeyspaceOp::RENAME) { op->status &= table->Get(&transaction, op->key, vdata); if (op->status) { // value doesn't change op->status &= table->Set(&transaction, op->newKey, vdata); if (op->status) op->status &= table->Delete(&transaction, op->key); } op->service->OnComplete(op); } else if (op->type == KeyspaceOp::DELETE) { op->status &= table->Delete(&transaction, op->key); op->service->OnComplete(op); } else if (op->type == KeyspaceOp::REMOVE) { op->value.Allocate(KEYSPACE_VAL_SIZE); op->status &= table->Get(&transaction, op->key, vdata); if (op->status) { ReadValue(vdata, storedPaxosID, storedCommandID, userValue); op->value.Set(userValue); op->status &= table->Delete(&transaction, op->key); } op->service->OnComplete(op); } else if (op->type == KeyspaceOp::PRUNE) { op->status &= table->Prune(&transaction, op->prefix); op->service->OnComplete(op); } else if (op->type == KeyspaceOp::SET_EXPIRY) { Log_Trace("Setting expiry for key: %.*s", op->key.length, op->key.buffer); // check old expiry WriteExpiryKey(kdata, op->key); if (table->Get(&transaction, kdata, vdata)) { // this key already had an expiry expiryTime = strntouint64(vdata.buffer, vdata.length, &nread); if (nread < 1) ASSERT_FAIL(); // delete old value WriteExpiryTime(kdata, expiryTime, op->key); table->Delete(&transaction, kdata); } // write !!t:<expirytime>:<key> => NULL WriteExpiryTime(kdata, op->nextExpiryTime, op->key); op->value.Clear(); table->Set(&transaction, kdata, op->value); // write !!k:<key> => <expiryTime> WriteExpiryKey(kdata, op->key); table->Set(&transaction, kdata, op->nextExpiryTime); InitExpiryTimer(); op->status = true; op->service->OnComplete(op); } else if (op->type == KeyspaceOp::REMOVE_EXPIRY) { Log_Trace("Removing expiry for key: %.*s", op->key.length, op->key.buffer); // check old expiry WriteExpiryKey(kdata, op->key); if (table->Get(&transaction, kdata, vdata)) { // this key already had an expiry expiryTime = strntouint64(vdata.buffer, vdata.length, &nread); if (nread < 1) ASSERT_FAIL(); // delete old value WriteExpiryTime(kdata, expiryTime, op->key); table->Delete(&transaction, kdata); } WriteExpiryKey(kdata, op->key); table->Delete(&transaction, kdata); InitExpiryTimer(); op->status = true; op->service->OnComplete(op); } else if (op->type == KeyspaceOp::CLEAR_EXPIRIES) { Log_Trace("Clearing all expiries"); kdata.Writef("!!"); table->Prune(&transaction, kdata, true); InitExpiryTimer(); op->status = true; op->service->OnComplete(op); } else ASSERT_FAIL(); return true; }