Exemplo n.º 1
0
PcpNodeRef
PcpPrimIndex_Graph::_InsertChildInStrengthOrder(
    size_t parentNodeIdx, size_t childNodeIdx)
{
    TF_VERIFY(parentNodeIdx < _GetNumNodes());
    TF_VERIFY(childNodeIdx < _GetNumNodes());

    // Insert the child in the list of children, maintaining
    // the relative strength order.
    _Node& parentNode = _data->nodes[parentNodeIdx];
    _Node& childNode  = _data->nodes[childNodeIdx];
    _ArcStrengthOrder comp(this);
    if (FIRST_CHILD(parentNode) == _Node::_invalidNodeIndex) {
        // No children yet so this is the first child.
        TF_VERIFY(LAST_CHILD(parentNode) == _Node::_invalidNodeIndex);

        FIRST_CHILD(parentNode) =
        LAST_CHILD(parentNode)  = childNodeIdx;
    }
    else if (comp(childNodeIdx, FIRST_CHILD(parentNode))) {
        // New first child.
        TF_VERIFY(LAST_CHILD(parentNode) != _Node::_invalidNodeIndex);

        _Node& nextNode = _data->nodes[FIRST_CHILD(parentNode)];
        NEXT_SIBLING(childNode) = FIRST_CHILD(parentNode);
        PREV_SIBLING(nextNode)  = childNodeIdx;
        FIRST_CHILD(parentNode) = childNodeIdx;
    }
    else if (!comp(childNodeIdx, LAST_CHILD(parentNode))) {
        // New last child.
        _Node& prevNode = _data->nodes[LAST_CHILD(parentNode)];
        PREV_SIBLING(childNode) = LAST_CHILD(parentNode);
        NEXT_SIBLING(prevNode)  = childNodeIdx;
        LAST_CHILD(parentNode)  = childNodeIdx;
    }
    else {
        // Child goes somewhere internal to the sibling linked list.
        for (size_t index = FIRST_CHILD(parentNode);
                index != _Node::_invalidNodeIndex;
                index = NEXT_SIBLING(_data->nodes[index])) {
            if (comp(childNodeIdx, index)) {
                _Node& nextNode = _data->nodes[index];
                TF_VERIFY(PREV_SIBLING(nextNode) != _Node::_invalidNodeIndex);
                _Node& prevNode =_data->nodes[PREV_SIBLING(nextNode)];
                PREV_SIBLING(childNode) = PREV_SIBLING(nextNode);
                NEXT_SIBLING(childNode) = index;
                PREV_SIBLING(nextNode)  = childNodeIdx;
                NEXT_SIBLING(prevNode)  = childNodeIdx;
                break;
            }
        }
    }

    return PcpNodeRef(this, childNodeIdx);
}
Exemplo n.º 2
0
size_t
PcpPrimIndex_Graph::_CreateNodesForSubgraph(
    const PcpPrimIndex_Graph& subgraph, const PcpArc& arc)
{
    // The subgraph's root should never have a parent or origin node; we
    // rely on this invariant below.
    TF_VERIFY(!subgraph.GetRootNode().GetParentNode() &&
              !subgraph.GetRootNode().GetOriginNode());

    // Insert a copy of all of the node data in the given subgraph into our
    // node pool.
    const size_t oldNumNodes = _GetNumNodes();
    _data->finalized = false;
    _data->nodes.insert(
        _data->nodes.end(), 
        subgraph._data->nodes.begin(), subgraph._data->nodes.end());
    _nodeSitePaths.insert(
        _nodeSitePaths.end(), 
        subgraph._nodeSitePaths.begin(), subgraph._nodeSitePaths.end());
    _nodeHasSpecs.insert(
        _nodeHasSpecs.end(),
        subgraph._nodeHasSpecs.begin(), subgraph._nodeHasSpecs.end());        
    const size_t newNumNodes = _GetNumNodes();
    const size_t subgraphRootNodeIndex = oldNumNodes;

    // Set the arc connecting the root of the subgraph to the rest of the
    // graph.
    _Node& subgraphRoot = _data->nodes[subgraphRootNodeIndex];
    subgraphRoot.SetArc(arc);

    // XXX: This is very similar to code in _ApplyNodeIndexMapping that
    //      adjust node references. There must be a good way to factor
    //      all of that out...

    // Iterate over all of the newly-copied nodes and adjust references to
    // other nodes in the node pool.
    struct _ConvertOldToNewIndex {
        _ConvertOldToNewIndex(size_t base, size_t numNewNodes) :
            _base(base), _numNewNodes(numNewNodes) { }
        size_t operator()(size_t oldIndex) const
        {
            if (oldIndex != _Node::_invalidNodeIndex) {
                TF_VERIFY(oldIndex + _base < _numNewNodes);
                return oldIndex + _base;
            }
            else {
                return oldIndex;
            }
        }
        size_t _base;
        size_t _numNewNodes;
    };
    const _ConvertOldToNewIndex convertToNewIndex(subgraphRootNodeIndex,
                                                  newNumNodes);

    for (size_t i = oldNumNodes; i < newNumNodes; ++i) {
        _Node& newNode = _data->nodes[i];

        // Update the node's mapToRoot since it is now part of a new graph.
        if (i != subgraphRootNodeIndex) {
            newNode.mapToRoot =
                subgraphRoot.mapToRoot.Compose(newNode.mapToRoot);
        }

        // The parent and origin of the root of the newly-inserted subgraph 
        // don't need to be fixed up because it doesn't point to a node 
        // within the subgraph.
        if (i != subgraphRootNodeIndex) {
            PARENT(newNode) = convertToNewIndex(PARENT(newNode));
            ORIGIN(newNode) = convertToNewIndex(ORIGIN(newNode));
        }

        FIRST_CHILD(newNode)  = convertToNewIndex(FIRST_CHILD(newNode));
        LAST_CHILD(newNode)   = convertToNewIndex(LAST_CHILD(newNode));
        PREV_SIBLING(newNode) = convertToNewIndex(PREV_SIBLING(newNode));
        NEXT_SIBLING(newNode) = convertToNewIndex(NEXT_SIBLING(newNode));
    }

    return subgraphRootNodeIndex;
}
Exemplo n.º 3
0
void 
PcpPrimIndex_Graph::_ApplyNodeIndexMapping(
    const std::vector<size_t>& nodeIndexMap)
{
    _NodePool& oldNodes = _data->nodes;
    SdfPathVector& oldSitePaths = _nodeSitePaths;
    std::vector<bool>& oldHasSpecs = _nodeHasSpecs;
    TF_VERIFY(oldNodes.size() == oldSitePaths.size() &&
              oldNodes.size() == oldHasSpecs.size());
    TF_VERIFY(nodeIndexMap.size() == oldNodes.size());

    const size_t numNodesToErase = 
        std::count(nodeIndexMap.begin(), nodeIndexMap.end(), 
                   _Node::_invalidNodeIndex);

    const size_t oldNumNodes = oldNodes.size();
    const size_t newNumNodes = oldNumNodes - numNodesToErase;
    TF_VERIFY(newNumNodes <= oldNumNodes);

    struct _ConvertOldToNewIndex {
        _ConvertOldToNewIndex(const std::vector<size_t>& table,
                              size_t numNewNodes) : _table(table)
        {
            for (size_t i = 0, n = _table.size(); i != n; ++i) {
                TF_VERIFY(_table[i] < numNewNodes || 
                          _table[i] == _Node::_invalidNodeIndex);
            }
        }

        size_t operator()(size_t oldIndex) const
        {
            if (oldIndex != _Node::_invalidNodeIndex) {
                return _table[oldIndex];
            }
            else {
                return oldIndex;
            }
        }
        const std::vector<size_t>& _table;

    };

    const _ConvertOldToNewIndex convertToNewIndex(nodeIndexMap, newNumNodes);

    // If this mapping causes nodes to be erased, it's much more convenient
    // to fix up node indices to accommodate those erasures in the old node
    // pool before moving nodes to their new position. 
    if (numNodesToErase > 0) {
        for (size_t i = 0; i < oldNumNodes; ++i) {
            const size_t oldNodeIndex = i;
            const size_t newNodeIndex = convertToNewIndex(oldNodeIndex);

            _Node& node = _data->nodes[oldNodeIndex];

            // Sanity-check: If this node isn't going to be erased, its parent
            // can't be erased either.
            const bool nodeWillBeErased = 
                (newNodeIndex == _Node::_invalidNodeIndex);
            if (!nodeWillBeErased) {
                const bool parentWillBeErased = 
                    PARENT(node) != _Node::_invalidNodeIndex &&
                    convertToNewIndex(PARENT(node)) == _Node::_invalidNodeIndex;
                TF_VERIFY(!parentWillBeErased);
                continue;
            }

            if (PREV_SIBLING(node) != _Node::_invalidNodeIndex) {
                _Node& prevNode = _data->nodes[PREV_SIBLING(node)];
                NEXT_SIBLING(prevNode) = NEXT_SIBLING(node);
            }
            if (NEXT_SIBLING(node) != _Node::_invalidNodeIndex) {
                _Node& nextNode = _data->nodes[NEXT_SIBLING(node)];
                PREV_SIBLING(nextNode) = PREV_SIBLING(node);
            }

            _Node& parentNode = _data->nodes[PARENT(node)];
            if (FIRST_CHILD(parentNode) == oldNodeIndex) {
                FIRST_CHILD(parentNode) = NEXT_SIBLING(node);
            }
            if (LAST_CHILD(parentNode) == oldNodeIndex) {
                LAST_CHILD(parentNode) = PREV_SIBLING(node);
            }
        }
    }

    // Swap nodes into their new position.
    _NodePool nodesAfterMapping(newNumNodes);
    SdfPathVector nodeSitePathsAfterMapping(newNumNodes);
    std::vector<bool> nodeHasSpecsAfterMapping(newNumNodes);

    for (size_t i = 0; i < oldNumNodes; ++i) {
        const size_t oldNodeIndex = i;
        const size_t newNodeIndex = convertToNewIndex(oldNodeIndex);
        if (newNodeIndex == _Node::_invalidNodeIndex) {
            continue;
        }

        // Swap the node from the old node pool into the new node pool at
        // the desired location.
        _Node& oldNode = oldNodes[oldNodeIndex];
        _Node& newNode = nodesAfterMapping[newNodeIndex];
        newNode.Swap(oldNode);

        PARENT(newNode)       = convertToNewIndex(PARENT(newNode));
        ORIGIN(newNode)       = convertToNewIndex(ORIGIN(newNode));
        FIRST_CHILD(newNode)  = convertToNewIndex(FIRST_CHILD(newNode));
        LAST_CHILD(newNode)   = convertToNewIndex(LAST_CHILD(newNode));
        PREV_SIBLING(newNode) = convertToNewIndex(PREV_SIBLING(newNode));
        NEXT_SIBLING(newNode) = convertToNewIndex(NEXT_SIBLING(newNode));

        // Copy the corresponding node site path.
        nodeSitePathsAfterMapping[newNodeIndex] = oldSitePaths[oldNodeIndex];
        nodeHasSpecsAfterMapping[newNodeIndex] = oldHasSpecs[oldNodeIndex];
    }

    _data->nodes.swap(nodesAfterMapping);
    _nodeSitePaths.swap(nodeSitePathsAfterMapping);
    _nodeHasSpecs.swap(nodeHasSpecsAfterMapping);
}
Exemplo n.º 4
0
                   int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
                   struct iatt *postbuf, dict_t *xdata)
{
        BARRIER_FOP_CBK (fsync, out, frame, this, op_ret, op_errno,
                         prebuf, postbuf, xdata);
out:
        return 0;
}

int32_t
barrier_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
                struct iovec *vector, int32_t count, off_t off, uint32_t flags,
                struct iobref *iobref, dict_t *xdata)
{
        if (!((flags | fd->flags) & (O_SYNC | O_DSYNC))) {
                STACK_WIND_TAIL (frame, FIRST_CHILD(this),
                                 FIRST_CHILD(this)->fops->writev,
                                 fd, vector, count, off, flags, iobref, xdata);

                return 0;
        }

        STACK_WIND (frame, barrier_writev_cbk, FIRST_CHILD(this),
                    FIRST_CHILD(this)->fops->writev, fd, vector, count,
                    off, flags, iobref, xdata);
        return 0;
}

int32_t
barrier_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
                      const char *name, dict_t *xdata)