Ejemplo n.º 1
0
void readPackAndWrite(
    uint64_t& writeSize, packet::Packet& pkt,
    cybozu::util::File& fileW, bool doWriteDiff, DiscardType discardType,
    uint64_t fsyncIntervalSize,
    std::vector<char>& zero, AlignedArray& buf)
{
    const char *const FUNC = __func__;
    size_t size;
    pkt.read(size);
    verifyDiffPackSize(size, FUNC);
    buf.resize(size);
    pkt.read(buf.data(), buf.size());

    verifyDiffPack(buf.data(), buf.size(), true);
    if (doWriteDiff) {
        fileW.write(buf.data(), buf.size());
    } else {
        MemoryDiffPack pack(buf.data(), buf.size());
        issueDiffPack(fileW, discardType, pack, zero);
    }
    writeSize += buf.size();
    if (writeSize >= fsyncIntervalSize) {
        fileW.fdatasync();
        writeSize = 0;
    }
}
Ejemplo n.º 2
0
/*
	read text data from fileName
*/
inline bool LoadFile(AlignedArray<char>& textBuf, const std::string& fileName)
{
	std::ifstream ifs(fileName.c_str(), std::ios::binary);
	if (!ifs) return false;
	ifs.seekg(0, std::ifstream::end);
	const size_t size = ifs.tellg();
	ifs.seekg(0);
	fprintf(stderr, "size=%d\n", (int)size);
	textBuf.resize(size + 1);
	ifs.read(&textBuf[0], size);
	textBuf[size] = '\0';
	return true;
}
Ejemplo n.º 3
0
void readAndSendHash(
    uint64_t& hashLb,
    packet::Packet& pkt, packet::StreamControl2& ctrl, Reader &reader,
    uint64_t sizeLb, size_t bulkLb,
    cybozu::murmurhash3::Hasher& hasher, AlignedArray& buf)
{
    const uint64_t lb = std::min<uint64_t>(sizeLb - hashLb, bulkLb);
    buf.resize(lb * LOGICAL_BLOCK_SIZE);
    reader.read(buf.data(), buf.size());
    const cybozu::murmurhash3::Hash hash = hasher(buf.data(), buf.size());
    doRetrySockIo(2, "ctrl.send.next", [&]() { ctrl.sendNext(); });
    pkt.write(hash);
    hashLb += lb;
}
uint64_t readAndValidateLogPackIo(cybozu::util::File& file, const device::SuperBlock& super, const LogPackHeader& logh)
{
    const uint32_t pbs = super.getPhysicalBlockSize();
    assert(logh.isValid());
    AlignedArray buf;
    for (size_t i = 0; i < logh.nRecords(); i++) {
        const WlogRecord &rec = logh.record(i);
        if (!rec.hasDataForChecksum()) continue;
        const uint64_t pb = super.getOffsetFromLsid(rec.lsid);
        const size_t ioSize = rec.ioSizeLb() * LBS;
        buf.resize(ioSize);
        file.pread(buf.data(), ioSize, pb * pbs);
        const uint32_t csum = cybozu::util::calcChecksum(buf.data(), buf.size(), logh.salt());
        if (csum == rec.checksum) continue;
        LOGs.info() << "INVALID_LOGPACK_IO" << rec << csum;
    }
    return logh.nextLogpackLsid();
}
Ejemplo n.º 5
0
inline bool dirtyHashSyncClient(
    packet::Packet &pkt, Reader &reader,
    uint64_t sizeLb, uint64_t bulkLb, uint32_t hashSeed,
    const std::atomic<int> &stopState, const ProcessStatus &ps,
    const std::atomic<uint64_t>& maxLbPerSec)
{
    const char *const FUNC = __func__;
    packet::StreamControl2 recvCtl(pkt.sock());
    packet::StreamControl2 sendCtl(pkt.sock());
    DiffPacker packer;
    walb::PackCompressor compr(::WALB_DIFF_CMPR_SNAPPY);
    cybozu::murmurhash3::Hasher hasher(hashSeed);
    ThroughputStabilizer thStab;

    uint64_t addr = 0;
    uint64_t remainingLb = sizeLb;
    AlignedArray buf;
    size_t cHash = 0, cSend = 0, cDummy = 0;
    try {
    for (;;) {
        if (stopState == ForceStopping || ps.isForceShutdown()) {
            return false;
        }
        dirty_hash_sync_local::doRetrySockIo(4, "ctrl.recv", [&]() { recvCtl.recv(); });
        if (recvCtl.isNext()) {
            if (remainingLb == 0) throw cybozu::Exception(FUNC) << "has next but remainingLb is zero";
        } else {
            if (remainingLb == 0) break;
            throw cybozu::Exception(FUNC) << "no next but remainingLb is not zero" << remainingLb;
        }
        cybozu::murmurhash3::Hash recvHash;
        pkt.read(recvHash);
        cHash++;

        const uint32_t lb = std::min<uint64_t>(remainingLb, bulkLb);
        buf.resize(lb * LOGICAL_BLOCK_SIZE);
        reader.read(buf.data(), buf.size());

        // to avoid socket timeout.
        dirty_hash_sync_local::doRetrySockIo(4, "ctrl.send.dummy", [&]() { sendCtl.sendDummy(); });
        cDummy++; cSend++;

        const cybozu::murmurhash3::Hash bdHash = hasher(buf.data(), buf.size());
        const uint64_t bgnAddr = packer.empty() ? addr : packer.header()[0].io_address;
        if (addr - bgnAddr >= DIRTY_HASH_SYNC_MAX_PACK_AREA_LB && !packer.empty()) {
            dirty_hash_sync_local::doRetrySockIo(4, "ctrl.send.next0", [&]() { sendCtl.sendNext(); });
            cSend++;
            dirty_hash_sync_local::compressAndSend(pkt, packer, compr);
        }
        if (recvHash != bdHash && !packer.add(addr, lb, buf.data())) {
            dirty_hash_sync_local::doRetrySockIo(4, "ctrl.send.next1", [&]() { sendCtl.sendNext(); });
            cSend++;
            dirty_hash_sync_local::compressAndSend(pkt, packer, compr);
            packer.add(addr, lb, buf.data());
        }
        pkt.flush();
        remainingLb -= lb;
        addr += lb;
        thStab.setMaxLbPerSec(maxLbPerSec.load());
        thStab.addAndSleepIfNecessary(lb, 10, 100);
    }
    } catch (...) {
        LOGs.warn() << "SEND_CTL" << cHash << cSend << cDummy;
        throw;
    }
    if (!packer.empty()) {
        dirty_hash_sync_local::doRetrySockIo(4, "ctrl.send.next2", [&]() { sendCtl.sendNext(); });
        cSend++;
        dirty_hash_sync_local::compressAndSend(pkt, packer, compr);
    }
    if (recvCtl.isError()) {
        throw cybozu::Exception(FUNC) << "recvCtl";
    }
    dirty_hash_sync_local::doRetrySockIo(4, "ctrl.send.next2", [&]() { sendCtl.sendEnd(); });
    pkt.flush();

    LOGs.debug() << "SEND_CTL" << cHash << cSend << cDummy;
    return true;
}