sttx::pointer transactionmaster::fetch (shamapitem::ref item,
        shamaptreenode::tntype type,
        bool checkdisk, std::uint32_t ucommitledger)
{
    sttx::pointer  txn;
    transaction::pointer            itx = getapp().getmastertransaction ().fetch (item->gettag (), false);

    if (!itx)
    {

        if (type == shamaptreenode::tntransaction_nm)
        {
            serializeriterator sit (item->peekserializer ());
            txn = std::make_shared<sttx> (std::ref (sit));
        }
        else if (type == shamaptreenode::tntransaction_md)
        {
            serializer s;
            int length;
            item->peekserializer ().getvl (s.moddata (), 0, length);
            serializeriterator sit (s);

            txn = std::make_shared<sttx> (std::ref (sit));
        }
    }
    else
    {
        if (ucommitledger)
            itx->setstatus (committed, ucommitledger);

        txn = itx->getstransaction ();
    }

    return txn;
}
Exemplo n.º 2
0
bool shamap::walkbranch (shamaptreenode* node,
                         shamapitem::ref othermapitem, bool isfirstmap,
                         delta& differences, int& maxcount)
{
    // walk a branch of a shamap that's matched by an empty branch or single item in the other map
    std::stack <shamaptreenode*, std::vector<shamaptreenode*>> nodestack;
    nodestack.push ({node});

    bool emptybranch = !othermapitem;

    while (!nodestack.empty ())
    {
        node = nodestack.top ();
        nodestack.pop ();

        if (node->isinner ())
        {
            // this is an inner node, add all non-empty branches
            for (int i = 0; i < 16; ++i)
                if (!node->isemptybranch (i))
                    nodestack.push ({descendthrow (node, i)});
        }
        else
        {
            // this is a leaf node, process its item
            shamapitem::pointer item = node->peekitem ();

            if (emptybranch || (item->gettag () != othermapitem->gettag ()))
            {
                // unmatched
                if (isfirstmap)
                    differences.insert (std::make_pair (item->gettag (),
                                      deltaref (item, shamapitem::pointer ())));
                else
                    differences.insert (std::make_pair (item->gettag (),
                                      deltaref (shamapitem::pointer (), item)));

                if (--maxcount <= 0)
                    return false;
            }
            else if (item->peekdata () != othermapitem->peekdata ())
            {
                // non-matching items with same tag
                if (isfirstmap)
                    differences.insert (std::make_pair (item->gettag (),
                                                deltaref (item, othermapitem)));
                else
                    differences.insert (std::make_pair (item->gettag (),
                                                deltaref (othermapitem, item)));

                if (--maxcount <= 0)
                    return false;

                emptybranch = true;
            }
            else
            {
                // exact match
                emptybranch = true;
            }
        }
    }

    if (!emptybranch)
    {
        // othermapitem was unmatched, must add
        if (isfirstmap) // this is first map, so other item is from second
            differences.insert (std::make_pair (othermapitem->gettag (),
                                                deltaref (shamapitem::pointer(),
                                                          othermapitem)));
        else
            differences.insert (std::make_pair (othermapitem->gettag (),
                                                deltaref (othermapitem,
                                                      shamapitem::pointer ())));

        if (--maxcount <= 0)
            return false;
    }

    return true;
}