void ReplicatedKeyspaceDB::Append() { ByteString bs; KeyspaceOp* op; KeyspaceOp**it; uint64_t expiryTime; Log_Trace(); if (ops.Length() == 0) return; pvalue.length = 0; bs.Set(pvalue); unsigned numAppended = 0; for (it = ops.Head(); it != NULL; it = ops.Next(it)) { op = *it; if (op->appended) ASSERT_FAIL(); if (op->IsExpiry() && op->type != KeyspaceOp::CLEAR_EXPIRIES) { // at this point we have up-to-date info on the expiry time expiryTime = GetExpiryTime(op->key); op->prevExpiryTime = expiryTime; } msg.FromKeyspaceOp(op); if (msg.Write(bs)) { pvalue.length += bs.length; bs.Advance(bs.length); op->appended = true; numAppended++; if (op->IsExpiry()) { // one expiry command per paxos round break; } } else break; } if (pvalue.length > 0) { estimatedLength -= pvalue.length; if (estimatedLength < 0) estimatedLength = 0; RLOG->Append(pvalue); Log_Trace("appending %d ops (length: %d)", numAppended, pvalue.length); } }
void ReplicatedKeyspaceDB::AsyncOnAppend() { Log_Trace(); unsigned nread; bool ret; uint64_t commandID; KeyspaceOp* op; KeyspaceOp** it; ByteString value; Stopwatch sw; value.Set(valueBuffer); Log_Trace("length: %d", value.length); numOps = 0; if (ownAppend) it = ops.Head(); else it = NULL; commandID = 0; while (true) { if (msg.Read(value, nread)) { sw.Start(); ret = Execute(transaction, paxosID, commandID); commandID++; sw.Stop(); value.Advance(nread); numOps++; if (ownAppend) { op = *it; if (op->type == KeyspaceOp::DIRTY_GET || op->type == KeyspaceOp::GET) ASSERT_FAIL(); if ((op->type == KeyspaceOp::ADD || op->type == KeyspaceOp::TEST_AND_SET || op->type == KeyspaceOp::REMOVE) && ret) op->value.Set(wdata); op->status = ret; it = ops.Next(it); } if (value.length == 0) break; } else { Log_Trace("Failed parsing:"); Log_Trace("%.*s", value.length, value.buffer); ASSERT_FAIL(); break; } } Log_Trace("time spent in Execute(): %ld", sw.elapsed); Log_Trace("numOps = %u", numOps); Log_Trace("ops/sec = %f", (double)1000*numOps/sw.elapsed); IOProcessor::Complete(&onAppendComplete); }