<commit_before>// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

#include <stdint.h>

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64_t nTimeLastCheckpoint;
        int64_t nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    bool fEnabled = true;

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (     0, uint256("0xa94f1aae8c409a0bd1e53cbca92d7e506b61c51d955cf56f76da501718d48d6c"))
        (     1, uint256("0x27fe28d8f814805c20aa2a2b31f629cb8a52d7016894541c5e424c18d6810559"))
        (     2, uint256("0x763ce0b24417ea00b642ba2e9980189d7c6d5f2cd0fd1574ac35e0e8d27fb405"))
        ( 10000, uint256("0x12697138ac647bec1ad807dd45827e67d7ed334bb47d823849e3dbbb48eebf64"))
        ( 20000, uint256("0x66099425a0ed2c3899e85e015e06f52a6138574d983829390e667ef4b5a9c89a"))
        ( 30000, uint256("0x1a49a6076a25f7e2ba68f39131f0788b3dda5ac504c59b24f6182be1247cf65a"))
        ( 40000, uint256("0x10d2e04152bf5c21b585a8c9720de6dc2c9f8440b70560cb9c796ccedd0b0ac3"))
        ( 50000, uint256("0x80c232bc7ca8ea6905fda51b017d9d4fe37523953d840765e96540ece0f2f3ba"))
        ( 60000, uint256("0x3913df09d0715aa54e1e44c5308dc475d1371f25029b619c609de2241d3c83e6"))
        ( 70000, uint256("0x345877d805e44fd1573dac836096ff1f3fd6a6604f0e51c665f2e7aea27f912b"))
        (100000, uint256("0xd6fccdd775246ca400c35fbd4ad2275b31a44f40efbf5cc45048abb77fde8be5"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1403072011, // * UNIX timestamp of last checkpoint block
        288130,   // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        300.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 0, uint256("0x78f33ce14ea7725092bd0ac5d0bc5f9b5718edfca48298b14e4d09248b141a4c"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1389199887,
        1,
        300.0
    };

    static MapCheckpoints mapCheckpointsRegtest =
        boost::assign::map_list_of
        ( 0, uint256("0xdeb6129ee5fbbf3ae8ca75e4650b5df2ba4241ff4b568506b2b3bff40b0c8a12"))
        ;
    static const CCheckpointData dataRegtest = {
        &mapCheckpointsRegtest,
        0,
        0,
        0.0
    };

    const CCheckpointData &Checkpoints() {
        if (Params().NetworkID() == CChainParams::TESTNET)
            return dataTestnet;
        else if (Params().NetworkID() == CChainParams::MAIN)
            return data;
        else
            return dataRegtest;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!fEnabled)
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64_t nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkpoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!fEnabled)
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!fEnabled)
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>New checkpoints<commit_after>// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

#include <stdint.h>

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64_t nTimeLastCheckpoint;
        int64_t nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    bool fEnabled = true;

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (     0, uint256("0xa94f1aae8c409a0bd1e53cbca92d7e506b61c51d955cf56f76da501718d48d6c"))
        (     1, uint256("0x27fe28d8f814805c20aa2a2b31f629cb8a52d7016894541c5e424c18d6810559"))
        (     2, uint256("0x763ce0b24417ea00b642ba2e9980189d7c6d5f2cd0fd1574ac35e0e8d27fb405"))
        ( 10000, uint256("0x12697138ac647bec1ad807dd45827e67d7ed334bb47d823849e3dbbb48eebf64"))
        ( 20000, uint256("0x66099425a0ed2c3899e85e015e06f52a6138574d983829390e667ef4b5a9c89a"))
        ( 30000, uint256("0x1a49a6076a25f7e2ba68f39131f0788b3dda5ac504c59b24f6182be1247cf65a"))
        ( 40000, uint256("0x10d2e04152bf5c21b585a8c9720de6dc2c9f8440b70560cb9c796ccedd0b0ac3"))
        ( 50000, uint256("0x80c232bc7ca8ea6905fda51b017d9d4fe37523953d840765e96540ece0f2f3ba"))
        ( 60000, uint256("0x3913df09d0715aa54e1e44c5308dc475d1371f25029b619c609de2241d3c83e6"))
        ( 70000, uint256("0x345877d805e44fd1573dac836096ff1f3fd6a6604f0e51c665f2e7aea27f912b"))
        (100000, uint256("0xd6fccdd775246ca400c35fbd4ad2275b31a44f40efbf5cc45048abb77fde8be5"))
        (130000, uint256("0x209b83ecac13e2176b980ffbac06bd5f27506abb62a1bf26e91c3fb1d9484431"))
        (160000, uint256("0x298309c8e4846b03387a9fd683e31867268b6cbc24598ce76aa00ab5d749d01d"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1409544271, // * UNIX timestamp of last checkpoint block
        368036,   // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        300.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 0, uint256("0x78f33ce14ea7725092bd0ac5d0bc5f9b5718edfca48298b14e4d09248b141a4c"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1389199887,
        1,
        300.0
    };

    static MapCheckpoints mapCheckpointsRegtest =
        boost::assign::map_list_of
        ( 0, uint256("0xdeb6129ee5fbbf3ae8ca75e4650b5df2ba4241ff4b568506b2b3bff40b0c8a12"))
        ;
    static const CCheckpointData dataRegtest = {
        &mapCheckpointsRegtest,
        0,
        0,
        0.0
    };

    const CCheckpointData &Checkpoints() {
        if (Params().NetworkID() == CChainParams::TESTNET)
            return dataTestnet;
        else if (Params().NetworkID() == CChainParams::MAIN)
            return data;
        else
            return dataRegtest;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!fEnabled)
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64_t nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkpoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!fEnabled)
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!fEnabled)
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>/*****************************************************************************
 * Copyright (C) 2011-2013 Michael Krufky
 *
 * Author: Michael Krufky <mkrufky@linuxtv.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include <inttypes.h>
#include "string.h"

#include "stats.h"
#include "log.h"
#define CLASS_MODULE "stats"

#define DBG 0

#define dprintf(fmt, arg...) __dprintf(DBG_STATS, "(%s) "fmt, parent, ##arg)

stats::stats(const char *caller)
  : tei_count(0)
  , __timenow(0)
  , parent(caller)
  , streamtime_cb(NULL)
  , streamtime_priv(NULL)
  , statistics_cb(NULL)
  , statistics_priv(NULL)
{
	dprintf("(%s)", parent);
}

stats::~stats()
{
	dprintf("(%s)", parent);
	show(false);
}

#if 0
stats::stats(const stats&)
{
	dprintf("(%s, copy)", parent);
}

stats& stats::operator= (const stats& cSource)
{
	dprintf("(%s, operator=)", parent);

	if (this == &cSource)
		return *this;

	return *this;
}
#endif

static void parse_pcr(uint8_t *pcr, uint64_t *pcr_base, unsigned int *pcr_ext)
{
	*pcr_base = (pcr[0] * 0x2000000) +
	            (pcr[1] * 0x20000) +
	            (pcr[2] * 0x200) +
	            (pcr[3] * 0x02) +
	            ((pcr[4] & 0x80) >> 7);

	*pcr_ext = ((pcr[4] & 0x01) * 0x100) + pcr[5];

	return;
}

static time_t walltime(void *p) { return time(NULL); }

char *stats_scale_unit(char *b, size_t n, uint64_t x)
{
	memset(b, 0, n);

	if (x >= 1000000) {
		if ((x % 1000000) < 100)
			snprintf(b, n, "%3" PRIu64 ".%03" PRIu64 " m", x / 1000000, x % 1000000);
		else
			snprintf(b, n, "%3" PRIu64 ".%03" PRIu64 " m", x / 1000000, x % 1000000);
	} else if (x >= 1000) {
		if ((x % 1000) < 100)
			snprintf(b, n, "%3" PRIu64 ".%03" PRIu64 " k", x / 1000, x % 1000);
		else
			snprintf(b, n, "%3" PRIu64 ".%03" PRIu64 " k", x / 1000, x % 1000);
	} else
		snprintf(b, n, "    %3" PRIu64 "  ", x);
	return b;
}

void stats::show(bool per_sec)
{
	if (statistics_cb) {
		statistics_cb(statistics_priv, statistics, discontinuities, tei_count, per_sec);
		return;
	}
	for (stats_map::const_iterator iter = statistics.begin(); iter != statistics.end(); ++iter) {
		char a[16];
		char b[16];
		dprintf("pid %04x %5" PRIu64 " p%s  %sb%s  %sbit",
			iter->first, iter->second / 188, (per_sec) ? "/s" : "",
			stats_scale_unit(a, sizeof(a), iter->second), (per_sec) ? "/s" : "",
			stats_scale_unit(b, sizeof(b), iter->second * 8));
	}
	for (stats_map::const_iterator iter = discontinuities.begin(); iter != discontinuities.end(); ++iter)
		dprintf("pid %04x\t%" PRIu64 " continuity errors (%" PRIu64 "%%)", iter->first, iter->second, ((!iter->second) || (!statistics[iter->first])) ? 0 : (!statistics.count(iter->first)) ? 0 : (100 * iter->second / (statistics[iter->first] / 188)));

	if (tei_count) dprintf("tei count: %" PRIu64 " (%" PRIu64 "%%)", tei_count, (!statistics[0x2000]) ? 0 : (18800 * tei_count / statistics[0x2000]));
}

void stats::push_pid(int c, const uint16_t pid)
{
	streamtime_callback cb = (streamtime_cb) ? streamtime_cb : &walltime;
	time_t timenow = cb(streamtime_priv);

	if (timenow > __timenow) {
		show();
		clear_stats();
		__timenow = timenow;
	}

	__push_pid(c, pid);
}

pkt_stats_t *stats::parse(const uint8_t *p, pkt_stats_t *pkt_stats)
{
	if (pkt_stats) {
		memset(pkt_stats, 0, sizeof(pkt_stats));

		const uint8_t *q = p;

		hdr.sync_byte          = q[0];
		hdr.tei                = (q[1] & 0x80) >> 7;
		hdr.payload_unit_start = (q[1] & 0x40) >> 6;
		hdr.transport_priority = (q[1] & 0x20) >> 5;
		hdr.pid                = ((q[1] & 0x1f) << 8) | q[2];
		hdr.scrambling         = (q[3] & 0xc0) >> 6;
		hdr.adaptation_flags   = (q[3] & 0x30) >> 4;
		hdr.continuity_ctr     = (q[3] & 0x0f);

		if (hdr.adaptation_flags & 0x02) {
			q += 4;
			adapt.field_length   = q[0];
			adapt.discontinuity  = (q[1] & 0x80) >> 7;
			adapt.random_access  = (q[1] & 0x40) >> 6; /* set to 1 if the PES pkt in this TS pkt starts an a/v sequence */
			adapt.es_priority    = (q[1] & 0x20) >> 5;
			adapt.pcr            = (q[1] & 0x10) >> 4;
			adapt.opcr           = (q[1] & 0x08) >> 3;
			adapt.splicing_point = (q[1] & 0x04) >> 2;
			adapt.tp_priv_data   = (q[1] & 0x02) >> 1;
			adapt.field_ext      = (q[1] & 0x01) >> 0;

			if (adapt.pcr) {
				memcpy(adapt.PCR, &q[2], 6);
				q += 6;
			}
			if (adapt.opcr) {
				memcpy(adapt.OPCR, &q[2], 6);
				q += 6;
			}
			if (adapt.splicing_point) {
				adapt.splicing_countdown = q[2];
				q ++;
			}
		}

		pkt_stats->sync_loss = (hdr.sync_byte != 0x47) ? true : false;
		if (!pkt_stats->sync_loss) {
			pkt_stats->tei = (hdr.tei) ? true : false;
			pkt_stats->pid = hdr.pid;
		} else
			pkt_stats->pid = (uint16_t) - 1;
	}
	return pkt_stats;
}

void stats::clear_stats()
{
	statistics.clear();
	discontinuities.clear();
	last_pcr_base.clear();
	tei_count = 0;
}

void stats::push_stats(pkt_stats_t *pkt_stats)
{
	if (pkt_stats->tei) {
		tei_count++;
		push_pid((uint16_t) - 1);
	} else
		push_pid(pkt_stats->pid);
}

void stats::push(const uint8_t *p, pkt_stats_t *pkt_stats)
{
	if (!pkt_stats) {
		__push(p);
		return;
	}

	memset(pkt_stats, 0, sizeof(pkt_stats));

	parse(p, pkt_stats);

	if (hdr.adaptation_flags & 0x01) {// payload present
		if (continuity.count(hdr.pid)) {
			uint8_t next = (continuity[hdr.pid] + 1) & 0x0f;
			if ((next != (hdr.continuity_ctr & 0x0f)) && (hdr.continuity_ctr + continuity[hdr.pid] > 0)) {
				if (!(hdr.adaptation_flags & 0x02) && (adapt.discontinuity)) {
					push_discontinuity(hdr.pid);
#if DBG
					dprintf("CONTINUITY ERROR pid: %04x cur: 0x%x prev 0x%x", hdr.pid, hdr.continuity_ctr, continuity[hdr.pid]);
#endif
				}
			}
		}
		continuity[hdr.pid] = hdr.continuity_ctr;
	}

	if (hdr.adaptation_flags & 0x02) {
		if (adapt.pcr) {
			uint64_t pcr_base;
			unsigned int pcr_ext;

			parse_pcr(adapt.PCR, &pcr_base, &pcr_ext);
			dprintf("PID: 0x%04x, PCR base: %ld, ext: %d", hdr.pid, pcr_base, pcr_ext);

			stats_map::const_iterator iter = last_pcr_base.find(hdr.pid);
			if ((iter != last_pcr_base.end()) && (pcr_base < iter->second))
				fprintf(stderr, "%s: PID: 0x%04x, %ld < %ld !!!\n", __func__, hdr.pid, pcr_base, iter->second);

			last_pcr_base[hdr.pid] = pcr_base;
		}
		if (adapt.opcr) {
			uint64_t pcr_base;
			unsigned int pcr_ext;

			parse_pcr(adapt.OPCR, &pcr_base, &pcr_ext);
			dprintf("PID: 0x%04x, PCR base: %ld, ext: %d", hdr.pid, pcr_base, pcr_ext);
		}
		if (adapt.splicing_point) {
			dprintf("PID: 0x%04x, splicing countdown: %d", hdr.pid, adapt.splicing_countdown);
		}
	}

	push_stats(pkt_stats);
}
<commit_msg>stats: fix warning: format ‘%ld’ expects argument of type ‘long int’, but argument 6 has type ‘uint64_t {aka long long unsigned int}’ [-Wformat]<commit_after>/*****************************************************************************
 * Copyright (C) 2011-2013 Michael Krufky
 *
 * Author: Michael Krufky <mkrufky@linuxtv.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include <inttypes.h>
#include "string.h"

#include "stats.h"
#include "log.h"
#define CLASS_MODULE "stats"

#define DBG 0

#define dprintf(fmt, arg...) __dprintf(DBG_STATS, "(%s) "fmt, parent, ##arg)

stats::stats(const char *caller)
  : tei_count(0)
  , __timenow(0)
  , parent(caller)
  , streamtime_cb(NULL)
  , streamtime_priv(NULL)
  , statistics_cb(NULL)
  , statistics_priv(NULL)
{
	dprintf("(%s)", parent);
}

stats::~stats()
{
	dprintf("(%s)", parent);
	show(false);
}

#if 0
stats::stats(const stats&)
{
	dprintf("(%s, copy)", parent);
}

stats& stats::operator= (const stats& cSource)
{
	dprintf("(%s, operator=)", parent);

	if (this == &cSource)
		return *this;

	return *this;
}
#endif

static void parse_pcr(uint8_t *pcr, uint64_t *pcr_base, unsigned int *pcr_ext)
{
	*pcr_base = (pcr[0] * 0x2000000) +
	            (pcr[1] * 0x20000) +
	            (pcr[2] * 0x200) +
	            (pcr[3] * 0x02) +
	            ((pcr[4] & 0x80) >> 7);

	*pcr_ext = ((pcr[4] & 0x01) * 0x100) + pcr[5];

	return;
}

static time_t walltime(void *p) { return time(NULL); }

char *stats_scale_unit(char *b, size_t n, uint64_t x)
{
	memset(b, 0, n);

	if (x >= 1000000) {
		if ((x % 1000000) < 100)
			snprintf(b, n, "%3" PRIu64 ".%03" PRIu64 " m", x / 1000000, x % 1000000);
		else
			snprintf(b, n, "%3" PRIu64 ".%03" PRIu64 " m", x / 1000000, x % 1000000);
	} else if (x >= 1000) {
		if ((x % 1000) < 100)
			snprintf(b, n, "%3" PRIu64 ".%03" PRIu64 " k", x / 1000, x % 1000);
		else
			snprintf(b, n, "%3" PRIu64 ".%03" PRIu64 " k", x / 1000, x % 1000);
	} else
		snprintf(b, n, "    %3" PRIu64 "  ", x);
	return b;
}

void stats::show(bool per_sec)
{
	if (statistics_cb) {
		statistics_cb(statistics_priv, statistics, discontinuities, tei_count, per_sec);
		return;
	}
	for (stats_map::const_iterator iter = statistics.begin(); iter != statistics.end(); ++iter) {
		char a[16];
		char b[16];
		dprintf("pid %04x %5" PRIu64 " p%s  %sb%s  %sbit",
			iter->first, iter->second / 188, (per_sec) ? "/s" : "",
			stats_scale_unit(a, sizeof(a), iter->second), (per_sec) ? "/s" : "",
			stats_scale_unit(b, sizeof(b), iter->second * 8));
	}
	for (stats_map::const_iterator iter = discontinuities.begin(); iter != discontinuities.end(); ++iter)
		dprintf("pid %04x\t%" PRIu64 " continuity errors (%" PRIu64 "%%)", iter->first, iter->second, ((!iter->second) || (!statistics[iter->first])) ? 0 : (!statistics.count(iter->first)) ? 0 : (100 * iter->second / (statistics[iter->first] / 188)));

	if (tei_count) dprintf("tei count: %" PRIu64 " (%" PRIu64 "%%)", tei_count, (!statistics[0x2000]) ? 0 : (18800 * tei_count / statistics[0x2000]));
}

void stats::push_pid(int c, const uint16_t pid)
{
	streamtime_callback cb = (streamtime_cb) ? streamtime_cb : &walltime;
	time_t timenow = cb(streamtime_priv);

	if (timenow > __timenow) {
		show();
		clear_stats();
		__timenow = timenow;
	}

	__push_pid(c, pid);
}

pkt_stats_t *stats::parse(const uint8_t *p, pkt_stats_t *pkt_stats)
{
	if (pkt_stats) {
		memset(pkt_stats, 0, sizeof(pkt_stats));

		const uint8_t *q = p;

		hdr.sync_byte          = q[0];
		hdr.tei                = (q[1] & 0x80) >> 7;
		hdr.payload_unit_start = (q[1] & 0x40) >> 6;
		hdr.transport_priority = (q[1] & 0x20) >> 5;
		hdr.pid                = ((q[1] & 0x1f) << 8) | q[2];
		hdr.scrambling         = (q[3] & 0xc0) >> 6;
		hdr.adaptation_flags   = (q[3] & 0x30) >> 4;
		hdr.continuity_ctr     = (q[3] & 0x0f);

		if (hdr.adaptation_flags & 0x02) {
			q += 4;
			adapt.field_length   = q[0];
			adapt.discontinuity  = (q[1] & 0x80) >> 7;
			adapt.random_access  = (q[1] & 0x40) >> 6; /* set to 1 if the PES pkt in this TS pkt starts an a/v sequence */
			adapt.es_priority    = (q[1] & 0x20) >> 5;
			adapt.pcr            = (q[1] & 0x10) >> 4;
			adapt.opcr           = (q[1] & 0x08) >> 3;
			adapt.splicing_point = (q[1] & 0x04) >> 2;
			adapt.tp_priv_data   = (q[1] & 0x02) >> 1;
			adapt.field_ext      = (q[1] & 0x01) >> 0;

			if (adapt.pcr) {
				memcpy(adapt.PCR, &q[2], 6);
				q += 6;
			}
			if (adapt.opcr) {
				memcpy(adapt.OPCR, &q[2], 6);
				q += 6;
			}
			if (adapt.splicing_point) {
				adapt.splicing_countdown = q[2];
				q ++;
			}
		}

		pkt_stats->sync_loss = (hdr.sync_byte != 0x47) ? true : false;
		if (!pkt_stats->sync_loss) {
			pkt_stats->tei = (hdr.tei) ? true : false;
			pkt_stats->pid = hdr.pid;
		} else
			pkt_stats->pid = (uint16_t) - 1;
	}
	return pkt_stats;
}

void stats::clear_stats()
{
	statistics.clear();
	discontinuities.clear();
	last_pcr_base.clear();
	tei_count = 0;
}

void stats::push_stats(pkt_stats_t *pkt_stats)
{
	if (pkt_stats->tei) {
		tei_count++;
		push_pid((uint16_t) - 1);
	} else
		push_pid(pkt_stats->pid);
}

void stats::push(const uint8_t *p, pkt_stats_t *pkt_stats)
{
	if (!pkt_stats) {
		__push(p);
		return;
	}

	memset(pkt_stats, 0, sizeof(pkt_stats));

	parse(p, pkt_stats);

	if (hdr.adaptation_flags & 0x01) {// payload present
		if (continuity.count(hdr.pid)) {
			uint8_t next = (continuity[hdr.pid] + 1) & 0x0f;
			if ((next != (hdr.continuity_ctr & 0x0f)) && (hdr.continuity_ctr + continuity[hdr.pid] > 0)) {
				if (!(hdr.adaptation_flags & 0x02) && (adapt.discontinuity)) {
					push_discontinuity(hdr.pid);
#if DBG
					dprintf("CONTINUITY ERROR pid: %04x cur: 0x%x prev 0x%x", hdr.pid, hdr.continuity_ctr, continuity[hdr.pid]);
#endif
				}
			}
		}
		continuity[hdr.pid] = hdr.continuity_ctr;
	}

	if (hdr.adaptation_flags & 0x02) {
		if (adapt.pcr) {
			uint64_t pcr_base;
			unsigned int pcr_ext;

			parse_pcr(adapt.PCR, &pcr_base, &pcr_ext);
			dprintf("PID: 0x%04x, PCR base: %" PRIu64 ", ext: %d", hdr.pid, pcr_base, pcr_ext);

			stats_map::const_iterator iter = last_pcr_base.find(hdr.pid);
			if ((iter != last_pcr_base.end()) && (pcr_base < iter->second))
				fprintf(stderr, "%s: PID: 0x%04x, %" PRIu64 " < %" PRIu64 " !!!\n",
					__func__, hdr.pid, pcr_base, iter->second);

			last_pcr_base[hdr.pid] = pcr_base;
		}
		if (adapt.opcr) {
			uint64_t pcr_base;
			unsigned int pcr_ext;

			parse_pcr(adapt.OPCR, &pcr_base, &pcr_ext);
			dprintf("PID: 0x%04x, PCR base: %" PRIu64 ", ext: %d", hdr.pid, pcr_base, pcr_ext);
		}
		if (adapt.splicing_point) {
			dprintf("PID: 0x%04x, splicing countdown: %d", hdr.pid, adapt.splicing_countdown);
		}
	}

	push_stats(pkt_stats);
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (  1500, uint256("0x841a2965955dd288cfa707a755d05a54e45f8bd476835ec9af4402a2b59a2967"))
        (  4032, uint256("0x9ce90e427198fc0ef05e5905ce3503725b80e26afd35a987965fd7e3d9cf0846"))
        (  8064, uint256("0xeb984353fc5190f210651f150c40b8a4bab9eeeff0b729fcb3987da694430d70"))
        ( 16128, uint256("0x602edf1859b7f9a6af809f1d9b0e6cb66fdc1d4d9dcd7a4bec03e12a1ccd153d"))
        ( 23420, uint256("0xd80fdf9ca81afd0bd2b2a90ac3a9fe547da58f2530ec874e978fce0b5101b507"))
        ( 50000, uint256("0x69dc37eb029b68f075a5012dcc0419c127672adb4f3a32882b2b3e71d07a20a6"))
        ( 80000, uint256("0x4fcb7c02f676a300503f49c764a89955a8f920b46a8cbecb4867182ecdb2e90a"))
        (120000, uint256("0xbd9d26924f05f6daa7f0155f32828ec89e8e29cee9e7121b026a7a3552ac6131"))
        (161500, uint256("0xdbe89880474f4bb4f75c227c77ba1cdc024991123b28b8418dbbf7798471ff43"))
        (179620, uint256("0x2ad9c65c990ac00426d18e446e0fd7be2ffa69e9a7dcb28358a50b2b78b9f709"))
        (240000, uint256("0x7140d1c4b4c2157ca217ee7636f24c9c73db39c4590c4e6eab2e3ea1555088aa"))
        (383640, uint256("0x2b6809f094a9215bafc65eb3f110a35127a34be94b7d0590a096c3f126c6f364"))
        (409004, uint256("0x487518d663d9f1fa08611d9395ad74d982b667fbdc0e77e9cf39b4f1355908a3"))
        (456000, uint256("0xbf34f71cc6366cd487930d06be22f897e34ca6a40501ac7d401be32456372004"))
        (541794, uint256("0x1cbccbe6920e7c258bbce1f26211084efb19764aa3224bec3f4320d77d6a2fd2"))
        (585010, uint256("0xea9ea06840de20a18a66acb07c9102ee6374ad2cbafc71794e576354fea5df2d"))
        (638902, uint256("0x15238656e8ec63d28de29a8c75fcf3a5819afc953dcd9cc45cecc53baec74f38"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1410516073, // * UNIX timestamp of last checkpoint block
        4896865,    // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        7000.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        (   546, uint256("0xa0fea99a6897f531600c8ae53367b126824fd6a847b2b2b73817a95b8e27e602"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1365458829,
        547,
        576
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>Update checkpoints<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
 ( 0, uint256("0x"))
 ;
    static const CCheckpointData data = {
        &mapCheckpoints,
//        1410516073, // * UNIX timestamp of last checkpoint block
//        4896865,    // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
//        7000.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
  //      (   546, uint256("0xa0fea99a6897f531600c8ae53367b126824fd6a847b2b2b73817a95b8e27e602"))
( 0, uint256("0x"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
      //  1365458829,
      //  547,
      //  576
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>/*
 * Chromaprint -- Audio fingerprinting toolkit
 * Copyright (C) 2010  Lukas Lalinsky <lalinsky@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 * USA
 */

#include <vector>
#include <string>
#include <algorithm>
#include <chromaprint.h>
#include "fingerprinter.h"
#include "fingerprint_compressor.h"
#include "fingerprint_decompressor.h"
#include "fingerprinter_configuration.h"
#include "base64.h"

using namespace std;
using namespace Chromaprint;

extern "C" {

struct ChromaprintContextPrivate {
	int algorithm;
	Fingerprinter *fingerprinter;
	vector<int32_t> fingerprint;
};

#define STR(x) #x
#define VERSION_STR(minor, major, patch) \
	STR(major) "." STR(minor) "." STR(patch)

static const char *version_str = VERSION_STR(
	CHROMAPRINT_VERSION_MAJOR,
	CHROMAPRINT_VERSION_MINOR,
	CHROMAPRINT_VERSION_PATCH);

const char *chromaprint_get_version(void)
{
	return version_str;
}

ChromaprintContext *chromaprint_new(int algorithm)
{
	ChromaprintContextPrivate *ctx = new ChromaprintContextPrivate();
	ctx->algorithm = algorithm;
	ctx->fingerprinter = new Fingerprinter(CreateFingerprinterConfiguration(algorithm));
	return (ChromaprintContext *)ctx;
}

void chromaprint_free(ChromaprintContext *c)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	delete ctx->fingerprinter;
	delete ctx;
}

int chromaprint_start(ChromaprintContext *c, int sample_rate, int num_channels)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	return ctx->fingerprinter->Start(sample_rate, num_channels) ? 1 : 0;
}

int chromaprint_feed(ChromaprintContext *c, void *data, int length)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	ctx->fingerprinter->Consume((short *)data, length);
	return 1;
}

int chromaprint_finish(ChromaprintContext *c)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	ctx->fingerprint = ctx->fingerprinter->Finish();
	return 1;
}

int chromaprint_get_fingerprint(ChromaprintContext *c, char **data)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	string fp = Chromaprint::Base64Encode(Chromaprint::CompressFingerprint(ctx->fingerprint, ctx->algorithm));
	*data = (char *)malloc(fp.size() + 1);
	if (!*data) {
		return 0;
	}
	copy(fp.begin(), fp.end(), *data);
	(*data)[fp.size()] = 0;
	return 1;
}

int chromaprint_get_raw_fingerprint(ChromaprintContext *c, void **data, int *size)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	*data = malloc(sizeof(int32_t) * ctx->fingerprint.size());
	if (!*data) {
		return 0;
	}
	*size = ctx->fingerprint.size();
	copy(ctx->fingerprint.begin(), ctx->fingerprint.end(), *((int32_t **)data));
	return 1;
}

int chromaprint_encode_fingerprint(void *fp, int size, int algorithm, void **encoded_fp, int *encoded_size, int base64)
{
	vector<int32_t> uncompressed = vector<int32_t>((int32_t *)fp, (int32_t *)fp + size);
	string compressed = Chromaprint::CompressFingerprint(uncompressed, algorithm);
	if (!base64) {
		*encoded_fp = malloc(compressed.size());
		*encoded_size = compressed.size();
		copy(compressed.begin(), compressed.end(), (char *)*encoded_fp);
		return 1;
	}
	string encoded = Chromaprint::Base64Encode(compressed);
	*encoded_fp = malloc(encoded.size() + 1);
	*encoded_size = encoded.size();
	copy(encoded.begin(), encoded.end(), (char *)*encoded_fp);
	((char *)*encoded_fp)[encoded.size()] = 0;
	return 1;
}

int chromaprint_decode_fingerprint(void *encoded_fp, int encoded_size, void **fp, int *size, int *algorithm, int base64)
{
	string encoded = string((char *)encoded_fp, encoded_size);
	string compressed = base64 ? Chromaprint::Base64Decode(encoded) : encoded;
	vector<int32_t> uncompressed = Chromaprint::DecompressFingerprint(compressed, algorithm);
	*fp = malloc(sizeof(int32_t) * uncompressed.size());
	*size = uncompressed.size();
	copy(uncompressed.begin(), uncompressed.end(), (int32_t *)*fp);
	return 0;
}

void chromaprint_dealloc(void *ptr)
{
	free(ptr);
}

}
<commit_msg>Incorrect return code<commit_after>/*
 * Chromaprint -- Audio fingerprinting toolkit
 * Copyright (C) 2010  Lukas Lalinsky <lalinsky@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 * USA
 */

#include <vector>
#include <string>
#include <algorithm>
#include <chromaprint.h>
#include "fingerprinter.h"
#include "fingerprint_compressor.h"
#include "fingerprint_decompressor.h"
#include "fingerprinter_configuration.h"
#include "base64.h"

using namespace std;
using namespace Chromaprint;

extern "C" {

struct ChromaprintContextPrivate {
	int algorithm;
	Fingerprinter *fingerprinter;
	vector<int32_t> fingerprint;
};

#define STR(x) #x
#define VERSION_STR(minor, major, patch) \
	STR(major) "." STR(minor) "." STR(patch)

static const char *version_str = VERSION_STR(
	CHROMAPRINT_VERSION_MAJOR,
	CHROMAPRINT_VERSION_MINOR,
	CHROMAPRINT_VERSION_PATCH);

const char *chromaprint_get_version(void)
{
	return version_str;
}

ChromaprintContext *chromaprint_new(int algorithm)
{
	ChromaprintContextPrivate *ctx = new ChromaprintContextPrivate();
	ctx->algorithm = algorithm;
	ctx->fingerprinter = new Fingerprinter(CreateFingerprinterConfiguration(algorithm));
	return (ChromaprintContext *)ctx;
}

void chromaprint_free(ChromaprintContext *c)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	delete ctx->fingerprinter;
	delete ctx;
}

int chromaprint_start(ChromaprintContext *c, int sample_rate, int num_channels)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	return ctx->fingerprinter->Start(sample_rate, num_channels) ? 1 : 0;
}

int chromaprint_feed(ChromaprintContext *c, void *data, int length)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	ctx->fingerprinter->Consume((short *)data, length);
	return 1;
}

int chromaprint_finish(ChromaprintContext *c)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	ctx->fingerprint = ctx->fingerprinter->Finish();
	return 1;
}

int chromaprint_get_fingerprint(ChromaprintContext *c, char **data)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	string fp = Chromaprint::Base64Encode(Chromaprint::CompressFingerprint(ctx->fingerprint, ctx->algorithm));
	*data = (char *)malloc(fp.size() + 1);
	if (!*data) {
		return 0;
	}
	copy(fp.begin(), fp.end(), *data);
	(*data)[fp.size()] = 0;
	return 1;
}

int chromaprint_get_raw_fingerprint(ChromaprintContext *c, void **data, int *size)
{
	ChromaprintContextPrivate *ctx = (ChromaprintContextPrivate *)c;
	*data = malloc(sizeof(int32_t) * ctx->fingerprint.size());
	if (!*data) {
		return 0;
	}
	*size = ctx->fingerprint.size();
	copy(ctx->fingerprint.begin(), ctx->fingerprint.end(), *((int32_t **)data));
	return 1;
}

int chromaprint_encode_fingerprint(void *fp, int size, int algorithm, void **encoded_fp, int *encoded_size, int base64)
{
	vector<int32_t> uncompressed = vector<int32_t>((int32_t *)fp, (int32_t *)fp + size);
	string compressed = Chromaprint::CompressFingerprint(uncompressed, algorithm);
	if (!base64) {
		*encoded_fp = malloc(compressed.size());
		*encoded_size = compressed.size();
		copy(compressed.begin(), compressed.end(), (char *)*encoded_fp);
		return 1;
	}
	string encoded = Chromaprint::Base64Encode(compressed);
	*encoded_fp = malloc(encoded.size() + 1);
	*encoded_size = encoded.size();
	copy(encoded.begin(), encoded.end(), (char *)*encoded_fp);
	((char *)*encoded_fp)[encoded.size()] = 0;
	return 1;
}

int chromaprint_decode_fingerprint(void *encoded_fp, int encoded_size, void **fp, int *size, int *algorithm, int base64)
{
	string encoded = string((char *)encoded_fp, encoded_size);
	string compressed = base64 ? Chromaprint::Base64Decode(encoded) : encoded;
	vector<int32_t> uncompressed = Chromaprint::DecompressFingerprint(compressed, algorithm);
	*fp = malloc(sizeof(int32_t) * uncompressed.size());
	*size = uncompressed.size();
	copy(uncompressed.begin(), uncompressed.end(), (int32_t *)*fp);
	return 1;
}

void chromaprint_dealloc(void *ptr)
{
	free(ptr);
}

}
<|endoftext|>


<commit_before><?hh //strict

namespace specify\cli;

use specify\Config;

class Argument
{

    private ImmMap<string, mixed> $options;

    public function __construct(
        private ?Traversable<string> $argv = []
    )
    {
        $options = getopt('c:', ['config::']);
        $this->options = new ImmMap($options);
    }

    public function getConfigFile() : string
    {
        $value = (string) $this->getOption('c', 'config');

        if ($value === null) {
            return Config::FILE_NAME;
        }

        return $value;
    }

    /**
     * Get the option value for CLI
     *
     *
     * $value = $this->getOption('c', 'config'); //short name, long name
     *
     */
    private function getOption(...) : mixed
    {
        $value = null;
        $optionNames = func_get_args();

        foreach ($optionNames as $optionName) {
            $value = $this->options->get($optionName);
            if ($value === null) {
                continue;
            }
            break;
        }

        return $value;
    }

}
<commit_msg>fix bug<commit_after><?hh //strict

namespace specify\cli;

use specify\Config;

class Argument
{

    private ImmMap<string, mixed> $options;

    public function __construct(
        private ?Traversable<string> $argv = []
    )
    {
        $options = getopt('c:', ['config::']);
        $this->options = new ImmMap($options);
    }

    public function getConfigFile() : string
    {
        $value = $this->getOption('c', 'config');

        if ($value === null) {
            return Config::FILE_NAME;
        }

        return (string) $value;
    }

    /**
     * Get the option value for CLI
     *
     *
     * $value = $this->getOption('c', 'config'); //short name, long name
     *
     */
    private function getOption(...) : mixed
    {
        $value = null;
        $optionNames = func_get_args();

        foreach ($optionNames as $optionName) {
            $value = $this->options->get($optionName);
            if ($value === null) {
                continue;
            }
            break;
        }

        return $value;
    }

}
<|endoftext|>


<commit_before>/*
 * Game.hpp
 *
 *  Created on: 29 May 2014
 *      Author: Marco
 */

#ifndef GAME_HPP_
#define GAME_HPP_

#include <map>
#include <vector>
#include <string>
#include <queue>

#include "CollisionSystem.hpp"
#include "PositionManager.hpp"
#include "worldmap/Worldmap.hpp"
#include "worldmap/Block.hpp"
#include "time.h"
#include "RenderObject.hpp"

class PositionManager;
class RenderObjectManager;
class InputEvent;

typedef int FrameEvents;

static const double MOVE_STEP = 30;

typedef std::vector<Entity> EntityGroup;

class GameState {
public:
	GameState();

	PositionManager *getPositionManager() const { return positionManager; }
	RenderObjectManager *getRenderObjectManager() const { return renderManager; }

private:
	PositionManager *positionManager;
	RenderObjectManager *renderManager;
	CollisionSystem *collisionSystem;

	std::vector<EntityGroup> m_bullets;
	std::vector<EntityGroup> m_walls;
};

enum class ObjectDelta {
	ADDED,
	REMOVED,
	UPDATED
};

class RenderObjectDelta{
public:
    RenderObjectDelta() : m_updateType(), m_renderObject() {}
    RenderObjectDelta(ObjectDelta updateType, RenderObject renderObject) :
        m_updateType(updateType),
        m_renderObject(renderObject)
    {}

	ObjectDelta m_updateType;
	RenderObject m_renderObject;
};

class GameDelta {
public:
	GameDelta() :
		deltaPositions(),
		deltaOrientations(),
		deltaBoundingBoxes(),
		deltaRenderObjects()
	{}
	GameDelta(const GameDelta &src);
	GameDelta(Entity entity, Position pos);
	GameDelta(Entity entity, Coords coords);
	GameDelta(Entity entity, Orientation orientation);
	GameDelta(Entity entity, BoundingBox bb);
	GameDelta(Entity, RenderObject ro);

	GameDelta mergeDelta(const GameDelta &oldDelta) const;

	const std::map<Entity, Position>& getPositionsDelta() const
    {
		return deltaPositions;
    }
	const std::map<Entity, Orientation>& getOrientationsDelta() const
	{
		return deltaOrientations;
	}
	const std::map<Entity, BoundingBox>& getBoundingBoxDelta() const
		{
		return deltaBoundingBoxes;
		}

	std::map<Entity, RenderObjectDelta>& getRenderObjectsDelta()
		{
		return deltaRenderObjects;
		}

private:
	std::map<Entity, Position> deltaPositions;
	std::map<Entity, Orientation> deltaOrientations;
	std::map<Entity, BoundingBox> deltaBoundingBoxes;
	std::map<Entity, RenderObjectDelta> deltaRenderObjects;
};

// UserActions and Events -> readOnly GameState -> GameDelta
// GameDelta -> Systems -> modified GameDelta and Events

//void run(Game *g) {
//	delta = g.stepGame(user_input, 0.12);
//
//}

typedef enum
{
       IDLE,
       MOVE_RIGHT,
       MOVE_LEFT,
       MOVE_TOP,
       MOVE_DOWN,
       SHOOT,
       TURN
}UserActionType;

struct UserActions
{

};

typedef struct
{
	Entity entity;
	Position position;
	Orientation orientation;
	RenderObject renderObject;
} RealmRenderData;

typedef struct
{
	int realm;
	std::vector<RealmRenderData> realmData;
} RenderData;

class Player
{
public:
	Entity entity_main_body;
	Entity entity_top_body;
	Entity entity_cannon;
};

class Game {
public:
	Game();
	virtual ~Game();

	GameDelta loadMap(int realm, const Worldmap& world) const;
	void setup();

	std::vector<RenderData> getRenderData() const;

    GameDelta stepGame(const std::queue<InputEvent> *ie,
    					const double timeDelta) const;

	GameDelta runSystems(const GameDelta gd) const;

//    GameDelta entitySetPosition(Entity entity, Position newPosition) const;
    GameDelta entityTranslate(Entity entity, Position delta) const;
    GameDelta entityRotate(Entity entity, Orientation orientation) const;
    GameDelta entitySetBoundingBox(Entity entity, BoundingBox bb) const;
    GameDelta entitySetRenderObject(Entity entity, RenderObject ro) const;

    // update game state
    void applyGameDelta(GameDelta gd);

    Entity getEntityById(EntityId id) const;
    Entity getEntityByName(std::string name) const;
    int getCurrentPlayer();
    Player getPlayerByID(int i) const;

    int getNumberOfPlayers() const;

private:
	GameState m_currentState;
    int m_currentPlayer;
//	std::map<EntityId, Entity> m_entities;

	std::vector<Player> m_players;
	std::vector<Worldmap> m_player_map;
};

#endif /* GAME_HPP_ */
<commit_msg>getCurrentGameState<commit_after>/*
 * Game.hpp
 *
 *  Created on: 29 May 2014
 *      Author: Marco
 */

#ifndef GAME_HPP_
#define GAME_HPP_

#include <map>
#include <vector>
#include <string>
#include <queue>

#include "CollisionSystem.hpp"
#include "PositionManager.hpp"
#include "worldmap/Worldmap.hpp"
#include "worldmap/Block.hpp"
#include "time.h"
#include "RenderObject.hpp"

class PositionManager;
class RenderObjectManager;
class InputEvent;

typedef int FrameEvents;

static const double MOVE_STEP = 30;

typedef std::vector<Entity> EntityGroup;

class GameState {
public:
	GameState();

	PositionManager *getPositionManager() const { return positionManager; }
	RenderObjectManager *getRenderObjectManager() const { return renderManager; }

private:
	PositionManager *positionManager;
	RenderObjectManager *renderManager;
	CollisionSystem *collisionSystem;

	std::vector<EntityGroup> m_bullets;
	std::vector<EntityGroup> m_walls;
};

enum class ObjectDelta {
	ADDED,
	REMOVED,
	UPDATED
};

class RenderObjectDelta{
public:
    RenderObjectDelta() : m_updateType(), m_renderObject() {}
    RenderObjectDelta(ObjectDelta updateType, RenderObject renderObject) :
        m_updateType(updateType),
        m_renderObject(renderObject)
    {}

	ObjectDelta m_updateType;
	RenderObject m_renderObject;
};

class GameDelta {
public:
	GameDelta() :
		deltaPositions(),
		deltaOrientations(),
		deltaBoundingBoxes(),
		deltaRenderObjects()
	{}
	GameDelta(const GameDelta &src);
	GameDelta(Entity entity, Position pos);
	GameDelta(Entity entity, Coords coords);
	GameDelta(Entity entity, Orientation orientation);
	GameDelta(Entity entity, BoundingBox bb);
	GameDelta(Entity, RenderObject ro);

	GameDelta mergeDelta(const GameDelta &oldDelta) const;

	const std::map<Entity, Position>& getPositionsDelta() const
    {
		return deltaPositions;
    }
	const std::map<Entity, Orientation>& getOrientationsDelta() const
	{
		return deltaOrientations;
	}
	const std::map<Entity, BoundingBox>& getBoundingBoxDelta() const
		{
		return deltaBoundingBoxes;
		}

	std::map<Entity, RenderObjectDelta>& getRenderObjectsDelta()
		{
		return deltaRenderObjects;
		}

private:
	std::map<Entity, Position> deltaPositions;
	std::map<Entity, Orientation> deltaOrientations;
	std::map<Entity, BoundingBox> deltaBoundingBoxes;
	std::map<Entity, RenderObjectDelta> deltaRenderObjects;
};

// UserActions and Events -> readOnly GameState -> GameDelta
// GameDelta -> Systems -> modified GameDelta and Events

//void run(Game *g) {
//	delta = g.stepGame(user_input, 0.12);
//
//}

typedef enum
{
       IDLE,
       MOVE_RIGHT,
       MOVE_LEFT,
       MOVE_TOP,
       MOVE_DOWN,
       SHOOT,
       TURN
}UserActionType;

struct UserActions
{

};

typedef struct
{
	Entity entity;
	Position position;
	Orientation orientation;
	RenderObject renderObject;
} RealmRenderData;

typedef struct
{
	int realm;
	std::vector<RealmRenderData> realmData;
} RenderData;

class Player
{
public:
	Entity entity_main_body;
	Entity entity_top_body;
	Entity entity_cannon;
};

class Game {
public:
	Game();
	virtual ~Game();

	GameDelta loadMap(int realm, const Worldmap& world) const;
	void setup();

	std::vector<RenderData> getRenderData() const;

    GameDelta stepGame(const std::queue<InputEvent> *ie,
    					const double timeDelta) const;

	GameDelta runSystems(const GameDelta gd) const;

//    GameDelta entitySetPosition(Entity entity, Position newPosition) const;
    GameDelta entityTranslate(Entity entity, Position delta) const;
    GameDelta entityRotate(Entity entity, Orientation orientation) const;
    GameDelta entitySetBoundingBox(Entity entity, BoundingBox bb) const;
    GameDelta entitySetRenderObject(Entity entity, RenderObject ro) const;

    // update game state
    void applyGameDelta(GameDelta gd);

    Entity getEntityById(EntityId id) const;
    Entity getEntityByName(std::string name) const;
    int getCurrentPlayer();
    Player getPlayerByID(int i) const;

    int getNumberOfPlayers() const;
    inline const GameState& getCurrentGameState() const;

private:
	GameState m_currentState;
    int m_currentPlayer;
//	std::map<EntityId, Entity> m_entities;

	std::vector<Player> m_players;
	std::vector<Worldmap> m_player_map;
};

const GameState& getCurrentGameState() const
{
    return m_currentState;
}
#endif /* GAME_HPP_ */
<|endoftext|>


<commit_before>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <visionaray/detail/macros.h>

#if defined(VSNRAY_OS_WIN32)
#include <windows.h>
#else
#include <unistd.h>
#endif

#include "util.h"

unsigned visionaray::get_num_processors()
{
#if defined(VSNRAY_OS_WIN32)

    SYSTEM_INFO sysinfo;
    GetNativeSystemInfo(&sysinfo);
    return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);

#else

    return static_cast<unsigned>(sysconf(_SC_NPROCESSORS_ONLN));

#endif
}
<commit_msg>Include platform header before determining OS<commit_after>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <visionaray/detail/macros.h>
#include <visionaray/detail/platform.h>

#if defined(VSNRAY_OS_WIN32)
#include <windows.h>
#else
#include <unistd.h>
#endif

#include "util.h"

unsigned visionaray::get_num_processors()
{
#if defined(VSNRAY_OS_WIN32)

    SYSTEM_INFO sysinfo;
    GetNativeSystemInfo(&sysinfo);
    return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);

#else

    return static_cast<unsigned>(sysconf(_SC_NPROCESSORS_ONLN));

#endif
}
<|endoftext|>


<commit_before>/*
* Copyright (c) 2020 Fredrik Mellbin
*
* This file is part of VapourSynth.
*
* VapourSynth is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* VapourSynth is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with VapourSynth; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "wave.h"
#include <cstring>
#include <bitset>

#ifdef _WIN32
#define WAVE_LITTLE_ENDIAN
#elif defined(__BYTE_ORDER__)
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define WAVE_BIG_ENDIAN
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define WAVE_LITTLE_ENDIAN
#endif
#endif

#ifdef WAVE_LITTLE_ENDIAN
#define WAVE_SWAP16(x) (x)
#define WAVE_SWAP32(x) (x)
#endif // WAVE_LITTLE_ENDIAN

#ifdef WAVE_BIG_ENDIAN
#define WAVE_SWAP16(x) __builtin_bswap16(x)
#define WAVE_SWAP32(x) __builtin_bswap32(x)
#endif // WAVE_BIG_ENDIAN

void PackChannels16to16le(const uint8_t *const *const Src, uint8_t *Dst, size_t Length, size_t Channels) {
    const uint16_t *const *const S = reinterpret_cast<const uint16_t *const *>(Src);
    uint16_t *D = reinterpret_cast<uint16_t *>(Dst);
    for (size_t i = 0; i < Length; i++) {
        for (size_t c = 0; c < Channels; c++)
            D[c] = WAVE_SWAP16(S[c][i]);
        D += Channels;
    }
}

void PackChannels32to32le(const uint8_t *const *const Src, uint8_t *Dst, size_t Length, size_t Channels) {
    const uint32_t *const *const S = reinterpret_cast<const uint32_t *const *>(Src);
    uint32_t *D = reinterpret_cast<uint32_t *>(Dst);
    for (size_t i = 0; i < Length; i++) {
        for (size_t c = 0; c < Channels; c++)
            D[c] = WAVE_SWAP32(S[c][i]);
        D += Channels;
    }
}

void PackChannels32to24le(const uint8_t *const *const Src, uint8_t *Dst, size_t Length, size_t Channels) {
    for (size_t i = 0; i < Length; i++) {
        for (size_t c = 0; c < Channels; c++) {
#ifdef WAVE_LITTLE_ENDIAN
            memcpy(Dst + c * 3, Src[c] + i * 4 + 1, 3);
#else
            Dst[c * 3 + 0] = Src[c][i * 4 + 2];
            Dst[c * 3 + 1] = Src[c][i * 4 + 1];
            Dst[c * 3 + 2] = Src[c][i * 4 + 0];
#endif
        }
        Dst += Channels * 3;
    }
}

static_assert(sizeof(WaveFormatExtensible) - offsetof(WaveFormatExtensible, wValidBitsPerSample) == 22, "");
static const uint8_t waveFormatExtensible[2] = { 0xFE, 0xFF };
static const uint8_t ksDataformatSubtypePCM[16] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 };
static const uint8_t ksDataformatSubtypeIEEEFloat[16] = { 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 };

static_assert(sizeof(WaveHeader) == 68, "");
static const uint8_t waveHdrRiffTagVal[4] = { 'R', 'I', 'F', 'F' };
static const uint8_t waveHdrWaveTagVal[4] = { 'W', 'A', 'V', 'E' };
static const uint8_t waveHdrFmtTagVal[4] = { 'f', 'm', 't', ' ' };
static const uint8_t waveHdrDataTagVal[4] = { 'd', 'a', 't', 'a' };

static_assert(sizeof(Wave64Header) == 128, "");
static const uint8_t wave64HdrRiffUuidVal[16] = { 0x72, 0x69, 0x66, 0x66, 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 };
static const uint8_t wave64HdrWaveUuidVal[16] = { 0x77, 0x61, 0x76, 0x65, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
static const uint8_t wave64HdrFmtUuidVal[16] = { 0x66, 0x6D, 0x74, 0x20, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
static const uint8_t wave64HdrDataUuidVal[16] = { 0x64, 0x61, 0x74, 0x61, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };

bool CreateWaveFormatExtensible(WaveFormatExtensible &header, bool IsFloat, int BitsPerSample, int SampleRate, uint64_t ChannelMask) {
    header = {};
    if (ChannelMask != static_cast<uint32_t>(ChannelMask))
        return false;
    std::bitset<64> tmp(ChannelMask);
    size_t NumChannels = tmp.count();
    size_t bytesPerOutputSample = (BitsPerSample + 7) / 8;

    memcpy(&header.wFormatTag, waveFormatExtensible, sizeof(waveFormatExtensible));
    header.nChannels = static_cast<uint16_t>(NumChannels);
    header.nSamplesPerSec = SampleRate;
    header.nBlockAlign = static_cast<uint16_t>(NumChannels * bytesPerOutputSample);
    header.nAvgBytesPerSec = static_cast<uint32_t>(NumChannels * bytesPerOutputSample * SampleRate);
    header.wBitsPerSample = static_cast<uint16_t>(bytesPerOutputSample * 8);
    header.cbSize = sizeof(WaveFormatExtensible) - offsetof(WaveFormatExtensible, wValidBitsPerSample);
    header.wValidBitsPerSample = BitsPerSample;
    header.dwChannelMask = static_cast<uint32_t>(ChannelMask);
    memcpy(&header.SubFormat, IsFloat ? ksDataformatSubtypeIEEEFloat : ksDataformatSubtypePCM, sizeof(ksDataformatSubtypePCM));
    return true;
}

bool CreateWave64Header(Wave64Header &header, bool IsFloat, int BitsPerSample, int SampleRate, uint64_t ChannelMask, int64_t NumSamples) {
    header = {};
    std::bitset<64> tmp(ChannelMask);
    size_t NumChannels = tmp.count();
    size_t bytesPerOutputSample = (BitsPerSample + 7) / 8;
    uint64_t dataSize = NumChannels * static_cast<uint64_t>(bytesPerOutputSample) * NumSamples;

    if (!CreateWaveFormatExtensible(header.wfx, IsFloat, BitsPerSample, SampleRate, ChannelMask))
        return false;

    memcpy(&header.riffUuid, wave64HdrRiffUuidVal, sizeof(wave64HdrRiffUuidVal));
    header.riffSize = sizeof(header) + dataSize;
    memcpy(&header.waveUuid, wave64HdrWaveUuidVal, sizeof(wave64HdrWaveUuidVal));
    memcpy(&header.fmtUuid, wave64HdrFmtUuidVal, sizeof(wave64HdrFmtUuidVal));
    header.fmtSize = sizeof(WaveFormatExtensible) + sizeof(header.fmtUuid) + sizeof(header.fmtSize);
    memcpy(&header.dataUuid, wave64HdrDataUuidVal, sizeof(wave64HdrDataUuidVal));
    header.dataSize = dataSize + sizeof(header.dataUuid) + sizeof(header.dataSize);
    return true;
}

bool CreateWaveHeader(WaveHeader &header, bool IsFloat, int BitsPerSample, int SampleRate, uint64_t ChannelMask, int64_t NumSamples) {
    header = {};
    std::bitset<64> tmp(ChannelMask);
    size_t NumChannels = tmp.count();
    size_t bytesPerOutputSample = (BitsPerSample + 7) / 8;
    uint64_t dataSize = NumChannels * static_cast<uint64_t>(bytesPerOutputSample) * NumSamples;

    if (sizeof(header) + dataSize > maxWaveFileSize)
        return false;

    if (!CreateWaveFormatExtensible(header.wfx, IsFloat, BitsPerSample, SampleRate, ChannelMask))
        return false;

    memcpy(&header.riffTag, waveHdrRiffTagVal, sizeof(waveHdrRiffTagVal));
    header.riffSize = static_cast<uint32_t>(sizeof(header) - sizeof(header.riffTag) - sizeof(header.riffSize) + dataSize);
    memcpy(&header.waveTag, waveHdrWaveTagVal, sizeof(waveHdrWaveTagVal));
    memcpy(&header.fmtTag, waveHdrFmtTagVal, sizeof(waveHdrFmtTagVal));
    header.fmtSize = sizeof(WaveFormatExtensible);
    memcpy(&header.dataTag, waveHdrDataTagVal, sizeof(waveHdrDataTagVal));
    header.dataSize = unsigned(dataSize);
    return true;
}
<commit_msg>Probably write wav/w64 headers correctly on big endian systems<commit_after>/*
* Copyright (c) 2020 Fredrik Mellbin
*
* This file is part of VapourSynth.
*
* VapourSynth is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* VapourSynth is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with VapourSynth; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "wave.h"
#include <cstring>
#include <bitset>

#ifdef _WIN32
#define WAVE_LITTLE_ENDIAN
#elif defined(__BYTE_ORDER__)
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define WAVE_BIG_ENDIAN
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define WAVE_LITTLE_ENDIAN
#endif
#endif

#ifdef WAVE_LITTLE_ENDIAN
#define WAVE_SWAP16_LE(x) (x)
#define WAVE_SWAP32_LE(x) (x)
#define WAVE_SWAP64_LE(x) (x)
#endif // WAVE_LITTLE_ENDIAN

#ifdef WAVE_BIG_ENDIAN
#define WAVE_SWAP16_LE(x) __builtin_bswap16(x)
#define WAVE_SWAP32_LE(x) __builtin_bswap32(x)
#define WAVE_SWAP64_LE(x) __builtin_bswap64(x)
#endif // WAVE_BIG_ENDIAN

void PackChannels16to16le(const uint8_t *const *const Src, uint8_t *Dst, size_t Length, size_t Channels) {
    const uint16_t *const *const S = reinterpret_cast<const uint16_t *const *>(Src);
    uint16_t *D = reinterpret_cast<uint16_t *>(Dst);
    for (size_t i = 0; i < Length; i++) {
        for (size_t c = 0; c < Channels; c++)
            D[c] = WAVE_SWAP16_LE(S[c][i]);
        D += Channels;
    }
}

void PackChannels32to32le(const uint8_t *const *const Src, uint8_t *Dst, size_t Length, size_t Channels) {
    const uint32_t *const *const S = reinterpret_cast<const uint32_t *const *>(Src);
    uint32_t *D = reinterpret_cast<uint32_t *>(Dst);
    for (size_t i = 0; i < Length; i++) {
        for (size_t c = 0; c < Channels; c++)
            D[c] = WAVE_SWAP32_LE(S[c][i]);
        D += Channels;
    }
}

void PackChannels32to24le(const uint8_t *const *const Src, uint8_t *Dst, size_t Length, size_t Channels) {
    for (size_t i = 0; i < Length; i++) {
        for (size_t c = 0; c < Channels; c++) {
#ifdef WAVE_LITTLE_ENDIAN
            memcpy(Dst + c * 3, Src[c] + i * 4 + 1, 3);
#else
            Dst[c * 3 + 0] = Src[c][i * 4 + 2];
            Dst[c * 3 + 1] = Src[c][i * 4 + 1];
            Dst[c * 3 + 2] = Src[c][i * 4 + 0];
#endif
        }
        Dst += Channels * 3;
    }
}

static_assert(sizeof(WaveFormatExtensible) - offsetof(WaveFormatExtensible, wValidBitsPerSample) == 22, "");
static const uint8_t waveFormatExtensible[2] = { 0xFE, 0xFF };
static const uint8_t ksDataformatSubtypePCM[16] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 };
static const uint8_t ksDataformatSubtypeIEEEFloat[16] = { 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 };

static_assert(sizeof(WaveHeader) == 68, "");
static const uint8_t waveHdrRiffTagVal[4] = { 'R', 'I', 'F', 'F' };
static const uint8_t waveHdrWaveTagVal[4] = { 'W', 'A', 'V', 'E' };
static const uint8_t waveHdrFmtTagVal[4] = { 'f', 'm', 't', ' ' };
static const uint8_t waveHdrDataTagVal[4] = { 'd', 'a', 't', 'a' };

static_assert(sizeof(Wave64Header) == 128, "");
static const uint8_t wave64HdrRiffUuidVal[16] = { 0x72, 0x69, 0x66, 0x66, 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 };
static const uint8_t wave64HdrWaveUuidVal[16] = { 0x77, 0x61, 0x76, 0x65, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
static const uint8_t wave64HdrFmtUuidVal[16] = { 0x66, 0x6D, 0x74, 0x20, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
static const uint8_t wave64HdrDataUuidVal[16] = { 0x64, 0x61, 0x74, 0x61, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };

bool CreateWaveFormatExtensible(WaveFormatExtensible &header, bool IsFloat, int BitsPerSample, int SampleRate, uint64_t ChannelMask) {
    header = {};
    if (ChannelMask != static_cast<uint32_t>(ChannelMask))
        return false;
    std::bitset<64> tmp(ChannelMask);
    size_t NumChannels = tmp.count();
    size_t bytesPerOutputSample = (BitsPerSample + 7) / 8;

    memcpy(&header.wFormatTag, waveFormatExtensible, sizeof(waveFormatExtensible));
    header.nChannels = WAVE_SWAP16_LE(static_cast<uint16_t>(NumChannels));
    header.nSamplesPerSec = WAVE_SWAP32_LE(SampleRate);
    header.nBlockAlign = WAVE_SWAP16_LE(static_cast<uint16_t>(NumChannels * bytesPerOutputSample));
    header.nAvgBytesPerSec = WAVE_SWAP32_LE(static_cast<uint32_t>(NumChannels * bytesPerOutputSample * SampleRate));
    header.wBitsPerSample = WAVE_SWAP16_LE(static_cast<uint16_t>(bytesPerOutputSample * 8));
    header.cbSize = WAVE_SWAP16_LE(sizeof(WaveFormatExtensible) - offsetof(WaveFormatExtensible, wValidBitsPerSample));
    header.wValidBitsPerSample = WAVE_SWAP16_LE(BitsPerSample);
    header.dwChannelMask = WAVE_SWAP32_LE(static_cast<uint32_t>(ChannelMask));
    memcpy(&header.SubFormat, IsFloat ? ksDataformatSubtypeIEEEFloat : ksDataformatSubtypePCM, sizeof(ksDataformatSubtypePCM));
    return true;
}

bool CreateWave64Header(Wave64Header &header, bool IsFloat, int BitsPerSample, int SampleRate, uint64_t ChannelMask, int64_t NumSamples) {
    header = {};
    std::bitset<64> tmp(ChannelMask);
    size_t NumChannels = tmp.count();
    size_t bytesPerOutputSample = (BitsPerSample + 7) / 8;
    uint64_t dataSize = NumChannels * static_cast<uint64_t>(bytesPerOutputSample) * NumSamples;

    if (!CreateWaveFormatExtensible(header.wfx, IsFloat, BitsPerSample, SampleRate, ChannelMask))
        return false;

    memcpy(&header.riffUuid, wave64HdrRiffUuidVal, sizeof(wave64HdrRiffUuidVal));
    header.riffSize = WAVE_SWAP64_LE(sizeof(header) + dataSize);
    memcpy(&header.waveUuid, wave64HdrWaveUuidVal, sizeof(wave64HdrWaveUuidVal));
    memcpy(&header.fmtUuid, wave64HdrFmtUuidVal, sizeof(wave64HdrFmtUuidVal));
    header.fmtSize = WAVE_SWAP64_LE(sizeof(WaveFormatExtensible) + sizeof(header.fmtUuid) + sizeof(header.fmtSize));
    memcpy(&header.dataUuid, wave64HdrDataUuidVal, sizeof(wave64HdrDataUuidVal));
    header.dataSize = WAVE_SWAP64_LE(dataSize + sizeof(header.dataUuid) + sizeof(header.dataSize));
    return true;
}

bool CreateWaveHeader(WaveHeader &header, bool IsFloat, int BitsPerSample, int SampleRate, uint64_t ChannelMask, int64_t NumSamples) {
    header = {};
    std::bitset<64> tmp(ChannelMask);
    size_t NumChannels = tmp.count();
    size_t bytesPerOutputSample = (BitsPerSample + 7) / 8;
    uint64_t dataSize = NumChannels * static_cast<uint64_t>(bytesPerOutputSample) * NumSamples;

    if (sizeof(header) + dataSize > maxWaveFileSize)
        return false;

    if (!CreateWaveFormatExtensible(header.wfx, IsFloat, BitsPerSample, SampleRate, ChannelMask))
        return false;

    memcpy(&header.riffTag, waveHdrRiffTagVal, sizeof(waveHdrRiffTagVal));
    header.riffSize = WAVE_SWAP32_LE(static_cast<uint32_t>(sizeof(header) - sizeof(header.riffTag) - sizeof(header.riffSize) + dataSize));
    memcpy(&header.waveTag, waveHdrWaveTagVal, sizeof(waveHdrWaveTagVal));
    memcpy(&header.fmtTag, waveHdrFmtTagVal, sizeof(waveHdrFmtTagVal));
    header.fmtSize = WAVE_SWAP32_LE(sizeof(WaveFormatExtensible));
    memcpy(&header.dataTag, waveHdrDataTagVal, sizeof(waveHdrDataTagVal));
    header.dataSize = WAVE_SWAP32_LE(static_cast<uint32_t>(dataSize));
    return true;
}
<|endoftext|>


<commit_before>// Copyright 2010-2012 RethinkDB, all rights reserved.
#ifndef CONFIG_ARGS_HPP_
#define CONFIG_ARGS_HPP_

#define KILOBYTE 1024LL
#define MEGABYTE (KILOBYTE * 1024LL)
#define GIGABYTE (MEGABYTE * 1024LL)
#define TERABYTE (GIGABYTE * 1024LL)

#define THOUSAND 1000LL
#define MILLION (THOUSAND * THOUSAND)
#define BILLION (THOUSAND * MILLION)

/*!
 * Version strings
 */

#define SOFTWARE_NAME_STRING "RethinkDB"
#define SERIALIZER_VERSION_STRING "1.8.alpha"

/**
 * Basic configuration parameters.
 */

// Defines the maximum size of the batch of IO events to process on
// each loop iteration. A larger number will increase throughput but
// decrease concurrency
#define MAX_IO_EVENT_PROCESSING_BATCH_SIZE        50

// The io batch factor ensures a minimum number of i/o operations
// which are picked from any specific i/o account consecutively.
// A higher value might be advantageous for throughput if seek times
// matter on the underlying i/o system. A low value improves latency.
// The advantage only holds as long as each account has a tendentially
// sequential set of i/o operations though. If access patterns are random
// for all accounts, a low io batch factor does just as well (as bad) when it comes
// to the number of random seeks, but might still provide a lower latency
// than a high batch factor. Our serializer writes usually generate a sequential
// access pattern and therefore take considerable advantage from a high io batch
// factor.
#define DEFAULT_IO_BATCH_FACTOR                   8

// Currently, each cache uses two IO accounts:
// one account for writes, and one account for reads.
// By adjusting the priorities of these accounts, reads
// can be prioritized over writes or the other way around.
//
// This is a one-per-serializer/file priority.
// The per-cache priorities are dynamically derived by dividing these priorities
// by the number of slices on a specific file.
#define CACHE_READS_IO_PRIORITY                   512
#define CACHE_WRITES_IO_PRIORITY                  64

// Garbage Colletion uses its own two IO accounts.
// There is one low-priority account that is meant to guarantee
// (performance-wise) unintrusive garbage collection.
// If the garbage ratio keeps growing,
// GC starts using the high priority account instead, which
// might have a negative influence on database performance
// under i/o heavy workloads but guarantees that the database
// doesn't grow indefinitely.
//
// This is a one-per-serializer/file priority.
#define GC_IO_PRIORITY_NICE                       8
#define GC_IO_PRIORITY_HIGH                       (4 * CACHE_WRITES_IO_PRIORITY)

// Size of the buffer used to perform IO operations (in bytes).
#define IO_BUFFER_SIZE                            (4 * KILOBYTE)

// Size of the device block size (in bytes)
#define DEVICE_BLOCK_SIZE                         512

// Size of each btree node (in bytes) on disk
#define DEFAULT_BTREE_BLOCK_SIZE                  (4 * KILOBYTE)

// Maximum number of data blocks
#define MAX_DATA_EXTENTS                          (TERABYTE / (16 * KILOBYTE))

// Size of each extent (in bytes)
#define DEFAULT_EXTENT_SIZE                       (512 * KILOBYTE)

// Max number of blocks which can be read ahead in one i/o transaction (if enabled)

// Ratio of free ram to use for the cache by default
// TODO: DEFAULT_MAX_CACHE_RATIO is unused. Should it be deleted?
#define DEFAULT_MAX_CACHE_RATIO                   0.5

// Maximum number of threads we support
// TODO: make this dynamic where possible
#define MAX_THREADS                               128

// Ticks (in milliseconds) the internal timed tasks are performed at
#define TIMER_TICKS_IN_MS                         5

// How many milliseconds to allow changes to sit in memory before flushing to disk
#define DEFAULT_FLUSH_TIMER_MS                    1000

// If non-null disk_ack_signals are present, concurrent flushing can be used to reduce the
// latency of each single flush. max_concurrent_flushes controls how many flushes can be active
// on a specific slice at any given time.
#define DEFAULT_MAX_CONCURRENT_FLUSHES            1

// If more than this many bytes of dirty data accumulate in the cache, then write
// transactions will be throttled.  A value of 0 means that it will automatically be
// set to MAX_UNSAVED_DATA_LIMIT_FRACTION times the max cache size
#define DEFAULT_UNSAVED_DATA_LIMIT                (4096 * MEGABYTE)

// The unsaved data limit cannot exceed this fraction of the max cache size
#define MAX_UNSAVED_DATA_LIMIT_FRACTION           0.9

// We start flushing dirty pages as soon as we hit this fraction of the unsaved data limit
#define FLUSH_AT_FRACTION_OF_UNSAVED_DATA_LIMIT   0.2

// How many times the page replacement algorithm tries to find an eligible page before giving up.
// Note that (MAX_UNSAVED_DATA_LIMIT_FRACTION ** PAGE_REPL_NUM_TRIES) is the probability that the
// page replacement algorithm will succeed on a given try, and if that probability is less than 1/2
// then the page replacement algorithm will on average be unable to evict pages from the cache.
#define PAGE_REPL_NUM_TRIES                       10

// How large can the key be, in bytes?  This value needs to fit in a byte.
#define MAX_KEY_SIZE                              250

// Any values of this size or less will be directly stored in btree leaf nodes.
// Values greater than this size will be stored in overflow blocks. This value
// needs to fit in a byte.
#define MAX_IN_NODE_VALUE_SIZE                    250

// memcached specifies the maximum value size to be 1MB, but customers asked this to be much higher
#define MAX_VALUE_SIZE                            (10 * MEGABYTE)

// Values larger than this will be streamed in a get operation
#define MAX_BUFFERED_GET_SIZE                     MAX_VALUE_SIZE // streaming is too slow for now, so we disable it completely

// If a single connection sends this many 'noreply' commands, the next command will
// have to wait until the first one finishes
#define MAX_CONCURRENT_QUERIES_PER_CONNECTION     500

// The number of concurrent queries when loading memcached operations from a file.
#define MAX_CONCURRENT_QUEURIES_ON_IMPORT         1000

// How many timestamps we store in a leaf node.  We store the
// NUM_LEAF_NODE_EARLIER_TIMES+1 most-recent timestamps.
#define NUM_LEAF_NODE_EARLIER_TIMES               4

// We assume that there will never be more than this many blocks held in memory by the cache at
// any one time. The value is computed by dividing 50 GB by the smallest reasonable block size.
// RSI: This value is stupid.  Remove it.
#define MAX_BLOCKS_IN_MEMORY                      (50 * GIGABYTE / KILOBYTE)

// Special block IDs.  These don't really belong here because they're
// more magic constants than tunable parameters.

// The btree superblock, which has a reference to the root node block
// id.
#define SUPERBLOCK_ID                             0

// The ratio at which we should start GCing.  (HEY: What's the extra
// 0.000001 in MAX_GC_HIGH_RATIO for?  Is it because we told the user
// that 0.99 was too high?)
#define DEFAULT_GC_HIGH_RATIO                     0.20
// TODO: MAX_GC_HIGH_RATIO is unused.  Use it!
// TODO: Probably this value is way too high.
//  - Keeping this around because if it becomes configurable again, we
//    should have these limits.  Before then at least rassert it.
#define MAX_GC_HIGH_RATIO                         0.990001

// The ratio at which we don't want to keep GC'ing.
#define DEFAULT_GC_LOW_RATIO                      0.15
// TODO: MIN_GC_LOW_RATIO is unused.  Use it!
//  - Keeping this around because if it becomes configurable again, we
//    should have these limits.  Before then at least rassert it.
#define MIN_GC_LOW_RATIO                          0.099999

// What's the maximum number of "young" extents we can have?
#define GC_YOUNG_EXTENT_MAX_SIZE                  50
// What's the definition of a "young" extent in microseconds?
#define GC_YOUNG_EXTENT_TIMELIMIT_MICROS          50000

// If the size of the LBA on a given disk exceeds LBA_MIN_SIZE_FOR_GC, then the fraction of the
// entries that are live and not garbage should be at least LBA_MIN_UNGARBAGE_FRACTION.
// TODO: Maybe change this back to 20 megabytes?
#define LBA_MIN_SIZE_FOR_GC                       (MEGABYTE * 1)
// TODO: This used to be 0.15 but we figured why not do the opposite of our well-tested parameter?
#define LBA_MIN_UNGARBAGE_FRACTION                0.85

// How many LBA structures to have for each file
// TODO: LBA_SHARD_FACTOR used to be 16.
#define LBA_SHARD_FACTOR                          4

// How many bytes of buffering space we can use per disk when reading the LBA. If it's set
// too high, then RethinkDB will eat a lot of memory at startup. This is bad because tcmalloc
// doesn't return memory to the OS. If it's set too low, startup will take a longer time.
#define LBA_READ_BUFFER_SIZE                      GIGABYTE

#define COROUTINE_STACK_SIZE                      131072

#define MAX_COROS_PER_THREAD                      10000

// Size of a cache line (used in cache_line_padded_t).
#define CACHE_LINE_SIZE                           64

#endif  // CONFIG_ARGS_HPP_

<commit_msg>Removed MAX_BLOCKS_IN_MEMORY.<commit_after>// Copyright 2010-2012 RethinkDB, all rights reserved.
#ifndef CONFIG_ARGS_HPP_
#define CONFIG_ARGS_HPP_

#define KILOBYTE 1024LL
#define MEGABYTE (KILOBYTE * 1024LL)
#define GIGABYTE (MEGABYTE * 1024LL)
#define TERABYTE (GIGABYTE * 1024LL)

#define THOUSAND 1000LL
#define MILLION (THOUSAND * THOUSAND)
#define BILLION (THOUSAND * MILLION)

/*!
 * Version strings
 */

#define SOFTWARE_NAME_STRING "RethinkDB"
#define SERIALIZER_VERSION_STRING "1.8.alpha"

/**
 * Basic configuration parameters.
 */

// Defines the maximum size of the batch of IO events to process on
// each loop iteration. A larger number will increase throughput but
// decrease concurrency
#define MAX_IO_EVENT_PROCESSING_BATCH_SIZE        50

// The io batch factor ensures a minimum number of i/o operations
// which are picked from any specific i/o account consecutively.
// A higher value might be advantageous for throughput if seek times
// matter on the underlying i/o system. A low value improves latency.
// The advantage only holds as long as each account has a tendentially
// sequential set of i/o operations though. If access patterns are random
// for all accounts, a low io batch factor does just as well (as bad) when it comes
// to the number of random seeks, but might still provide a lower latency
// than a high batch factor. Our serializer writes usually generate a sequential
// access pattern and therefore take considerable advantage from a high io batch
// factor.
#define DEFAULT_IO_BATCH_FACTOR                   8

// Currently, each cache uses two IO accounts:
// one account for writes, and one account for reads.
// By adjusting the priorities of these accounts, reads
// can be prioritized over writes or the other way around.
//
// This is a one-per-serializer/file priority.
// The per-cache priorities are dynamically derived by dividing these priorities
// by the number of slices on a specific file.
#define CACHE_READS_IO_PRIORITY                   512
#define CACHE_WRITES_IO_PRIORITY                  64

// Garbage Colletion uses its own two IO accounts.
// There is one low-priority account that is meant to guarantee
// (performance-wise) unintrusive garbage collection.
// If the garbage ratio keeps growing,
// GC starts using the high priority account instead, which
// might have a negative influence on database performance
// under i/o heavy workloads but guarantees that the database
// doesn't grow indefinitely.
//
// This is a one-per-serializer/file priority.
#define GC_IO_PRIORITY_NICE                       8
#define GC_IO_PRIORITY_HIGH                       (4 * CACHE_WRITES_IO_PRIORITY)

// Size of the buffer used to perform IO operations (in bytes).
#define IO_BUFFER_SIZE                            (4 * KILOBYTE)

// Size of the device block size (in bytes)
#define DEVICE_BLOCK_SIZE                         512

// Size of each btree node (in bytes) on disk
#define DEFAULT_BTREE_BLOCK_SIZE                  (4 * KILOBYTE)

// Maximum number of data blocks
#define MAX_DATA_EXTENTS                          (TERABYTE / (16 * KILOBYTE))

// Size of each extent (in bytes)
#define DEFAULT_EXTENT_SIZE                       (512 * KILOBYTE)

// Max number of blocks which can be read ahead in one i/o transaction (if enabled)

// Ratio of free ram to use for the cache by default
// TODO: DEFAULT_MAX_CACHE_RATIO is unused. Should it be deleted?
#define DEFAULT_MAX_CACHE_RATIO                   0.5

// Maximum number of threads we support
// TODO: make this dynamic where possible
#define MAX_THREADS                               128

// Ticks (in milliseconds) the internal timed tasks are performed at
#define TIMER_TICKS_IN_MS                         5

// How many milliseconds to allow changes to sit in memory before flushing to disk
#define DEFAULT_FLUSH_TIMER_MS                    1000

// If non-null disk_ack_signals are present, concurrent flushing can be used to reduce the
// latency of each single flush. max_concurrent_flushes controls how many flushes can be active
// on a specific slice at any given time.
#define DEFAULT_MAX_CONCURRENT_FLUSHES            1

// If more than this many bytes of dirty data accumulate in the cache, then write
// transactions will be throttled.  A value of 0 means that it will automatically be
// set to MAX_UNSAVED_DATA_LIMIT_FRACTION times the max cache size
#define DEFAULT_UNSAVED_DATA_LIMIT                (4096 * MEGABYTE)

// The unsaved data limit cannot exceed this fraction of the max cache size
#define MAX_UNSAVED_DATA_LIMIT_FRACTION           0.9

// We start flushing dirty pages as soon as we hit this fraction of the unsaved data limit
#define FLUSH_AT_FRACTION_OF_UNSAVED_DATA_LIMIT   0.2

// How many times the page replacement algorithm tries to find an eligible page before giving up.
// Note that (MAX_UNSAVED_DATA_LIMIT_FRACTION ** PAGE_REPL_NUM_TRIES) is the probability that the
// page replacement algorithm will succeed on a given try, and if that probability is less than 1/2
// then the page replacement algorithm will on average be unable to evict pages from the cache.
#define PAGE_REPL_NUM_TRIES                       10

// How large can the key be, in bytes?  This value needs to fit in a byte.
#define MAX_KEY_SIZE                              250

// Any values of this size or less will be directly stored in btree leaf nodes.
// Values greater than this size will be stored in overflow blocks. This value
// needs to fit in a byte.
#define MAX_IN_NODE_VALUE_SIZE                    250

// memcached specifies the maximum value size to be 1MB, but customers asked this to be much higher
#define MAX_VALUE_SIZE                            (10 * MEGABYTE)

// Values larger than this will be streamed in a get operation
#define MAX_BUFFERED_GET_SIZE                     MAX_VALUE_SIZE // streaming is too slow for now, so we disable it completely

// If a single connection sends this many 'noreply' commands, the next command will
// have to wait until the first one finishes
#define MAX_CONCURRENT_QUERIES_PER_CONNECTION     500

// The number of concurrent queries when loading memcached operations from a file.
#define MAX_CONCURRENT_QUEURIES_ON_IMPORT         1000

// How many timestamps we store in a leaf node.  We store the
// NUM_LEAF_NODE_EARLIER_TIMES+1 most-recent timestamps.
#define NUM_LEAF_NODE_EARLIER_TIMES               4

// Special block IDs.  These don't really belong here because they're
// more magic constants than tunable parameters.

// The btree superblock, which has a reference to the root node block
// id.
#define SUPERBLOCK_ID                             0

// The ratio at which we should start GCing.  (HEY: What's the extra
// 0.000001 in MAX_GC_HIGH_RATIO for?  Is it because we told the user
// that 0.99 was too high?)
#define DEFAULT_GC_HIGH_RATIO                     0.20
// TODO: MAX_GC_HIGH_RATIO is unused.  Use it!
// TODO: Probably this value is way too high.
//  - Keeping this around because if it becomes configurable again, we
//    should have these limits.  Before then at least rassert it.
#define MAX_GC_HIGH_RATIO                         0.990001

// The ratio at which we don't want to keep GC'ing.
#define DEFAULT_GC_LOW_RATIO                      0.15
// TODO: MIN_GC_LOW_RATIO is unused.  Use it!
//  - Keeping this around because if it becomes configurable again, we
//    should have these limits.  Before then at least rassert it.
#define MIN_GC_LOW_RATIO                          0.099999

// What's the maximum number of "young" extents we can have?
#define GC_YOUNG_EXTENT_MAX_SIZE                  50
// What's the definition of a "young" extent in microseconds?
#define GC_YOUNG_EXTENT_TIMELIMIT_MICROS          50000

// If the size of the LBA on a given disk exceeds LBA_MIN_SIZE_FOR_GC, then the fraction of the
// entries that are live and not garbage should be at least LBA_MIN_UNGARBAGE_FRACTION.
// TODO: Maybe change this back to 20 megabytes?
#define LBA_MIN_SIZE_FOR_GC                       (MEGABYTE * 1)
// TODO: This used to be 0.15 but we figured why not do the opposite of our well-tested parameter?
#define LBA_MIN_UNGARBAGE_FRACTION                0.85

// How many LBA structures to have for each file
// TODO: LBA_SHARD_FACTOR used to be 16.
#define LBA_SHARD_FACTOR                          4

// How many bytes of buffering space we can use per disk when reading the LBA. If it's set
// too high, then RethinkDB will eat a lot of memory at startup. This is bad because tcmalloc
// doesn't return memory to the OS. If it's set too low, startup will take a longer time.
#define LBA_READ_BUFFER_SIZE                      GIGABYTE

#define COROUTINE_STACK_SIZE                      131072

#define MAX_COROS_PER_THREAD                      10000

// Size of a cache line (used in cache_line_padded_t).
#define CACHE_LINE_SIZE                           64

#endif  // CONFIG_ARGS_HPP_

<|endoftext|>