void TreeRepository::appendNode(TreeNode* rawNode)
{
	TreeNodePtr bnode(rawNode);
	TreeNodePtr node(new CachedTreeNode(bnode));

	if (!this->getNode(node->getUid()))
	{
		// TODO need a more detailed change policy: invalidate only when parent/childe
		// structure is changed.
//		connect(node.get(), &TreeNode::changed, this, &TreeRepository::invalidated);
		connect(node.get(), &TreeNode::changed, this, &TreeRepository::onChanged);
		mNodes.push_back(node);
	}
}
Example #2
0
void
TestSimpleSuccessorArc(const char *name) {
    tbb::flow::graph g;
    {
        REMARK("Join<%s> successor test ", name);
        tbb::flow::join_node<tbb::flow::tuple<int>, JNODE_TYPE> qj(g);
        tbb::flow::broadcast_node<tbb::flow::tuple<int> > bnode(g);
        tbb::flow::make_edge(qj, bnode);
        ASSERT(!qj.my_successors.empty(),"successor missing after linking");
        g.reset();
        ASSERT(!qj.my_successors.empty(),"successor missing after reset()");
        g.reset(tbb::flow::rf_clear_edges);
        ASSERT(qj.my_successors.empty(), "successors not removed after reset(rf_clear_edges)");
    }
}
void
TestSimpleSuccessorArc(const char *name) {
    tbb::flow::graph g;
    {
        //tbb::flow::join_node<tbb::flow::tuple<int>, tbb::flow::queueing> qj(g);
        REMARK("Join<%s> successor test ", name);
        tbb::flow::join_node<tbb::flow::tuple<int>, JNODE_TYPE> qj(g);
        tbb::flow::broadcast_node<tbb::flow::tuple<int> > bnode(g);
        tbb::flow::make_edge(qj, bnode);
        ASSERT(!qj.my_successors.empty(),"successor missing after linking");
        g.reset();
        ASSERT(!qj.my_successors.empty(),"successor missing after reset()");
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
        g.reset(tbb::flow::rf_extract);
        ASSERT(qj.my_successors.empty(), "successors not removed after reset(rf_extract)");
#endif
    }
}
Example #4
0
void
TestSimpleSuccessorArc<tbb::flow::tag_matching>(const char *name) {
    tbb::flow::graph g;
    {
        REMARK("Join<%s> successor test ", name);
        typedef tbb::flow::tuple<int,int> my_tuple;
        tbb::flow::join_node<my_tuple, tbb::flow::tag_matching> qj(g,
                tag_func<int>(1),
                tag_func<int>(1)
                );
        tbb::flow::broadcast_node<my_tuple > bnode(g);
        tbb::flow::make_edge(qj, bnode);
        ASSERT(!qj.my_successors.empty(),"successor missing after linking");
        g.reset();
        ASSERT(!qj.my_successors.empty(),"successor missing after reset()");
        g.reset(tbb::flow::rf_clear_edges);
        ASSERT(qj.my_successors.empty(), "successors not removed after reset(rf_clear_edges)");
    }
}
// sequencer_node behaves like a queueing node, but requires a different constructor.
void
TestSequencerNode() {
    tbb::flow::graph g;
    tbb::flow::sequencer_node<int> bnode(g, seq_body());
    REMARK("Testing sequencer_node:");
    tbb::flow::function_node<int> fnode(g, tbb::flow::serial, serial_fn_body<int>(serial_fn_state0));
    REMARK("Testing sequencer_node:");
    serial_fn_state0 = 0;  // reset to waiting state.
    REMARK(" make_edge");
    tbb::flow::make_edge(bnode, fnode);
    ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after make_edge");
    REMARK(" try_put");
    bnode.try_put(0);  // will forward to the fnode
    BACKOFF_WAIT( serial_fn_state0 == 0, "timeout waiting for function_node");  // wait for the function_node to fire up
    ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after forwarding message");
    serial_fn_state0 = 0;
    g.wait_for_all();
    REMARK(" remove_edge");
    tbb::flow::remove_edge(bnode, fnode);
    ASSERT(bnode.my_successors.empty(), "buffering node has a successor after remove_edge");
    tbb::flow::join_node<tbb::flow::tuple<int,int>,tbb::flow::reserving> jnode(g);
    tbb::flow::make_edge(bnode, tbb::flow::input_port<0>(jnode));  // will spawn a task
    g.wait_for_all();
    ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after attaching to join");
    REMARK(" reverse");
    bnode.try_put(3);  // the edge should reverse
    g.wait_for_all();
    ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reserving");
    REMARK(" reset()");
    g.wait_for_all();
    g.reset();  // should be in forward direction again
    ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after reset()");
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
    REMARK(" remove_edge");
    g.reset(tbb::flow::rf_extract);  // should be in forward direction again
    ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reset(rf_extract)");
    ASSERT(fnode.my_predecessors.empty(), "buffering node reversed after reset(rf_extract)");
#endif
    REMARK("  done\n");
    g.wait_for_all();
}
Example #6
0
int main(int argc, char *argv[], char *envp[]) {
  char line[256];
  char ch;
  char *pwd;
  int i;
  cmd_ptr *cmdptr = NULL;

  pwd = malloc(sizeof(char) * 1024);
  jlist = jobs_init();
  //signal(SIGCHLD, SIG_DFL);
  signal(SIGINT,  SIG_IGN);
  signal(SIGTERM, SIG_IGN);
  signal(SIGQUIT, SIG_IGN);
  signal(SIGTSTP, SIG_IGN);
  signal(SIGSTOP, SIG_IGN);


  for (;;) {
    struct task *newtask;
    struct tnode *nodelist;
    strcpy(pwd, getenv("PWD"));
    printf("[CSC3150 shell:%s]$", pwd);

    line[0] = 0;
    i = 0;
    while ((ch = getchar()) != '\n')
      line[i++] = ch;
    line[i] = 0;
    if (line[0] == 0)
      continue;
    //temp=malloc(sizeof(char)*(strlen(line)+1));
    //strcpy(temp,line);
    if (!firstck(line)) {
      printf("Error: invalid input command line\n");
      continue;
    }
    //printf("Error\n");
    cmdptr = malloc(sizeof(cmd_ptr));
    initialize2(cmdptr);
    newtask = malloc(sizeof(struct task));
    newtask->cmd = malloc(sizeof(char) * (strlen(line) + 1));
    strcpy(newtask->cmd, line);
    jlist->job[jlist->n++] = newtask;

    if (start_chk(line) == 2) {
      nodelist = bnode(line);
      exec1(nodelist);
      continue;
    }
    if (start_chk(line) == 3)
      getcmd3(line, cmdptr);
    else if (start_chk(line) == 4)
      getcmd4(line, cmdptr);
    else if (start_chk(line) == 5)
      getcmd5(line, cmdptr);
    else if (start_chk(line) == 6)
      getcmd6(line, cmdptr);
    else if (start_chk(line) == 7)
      getcmd7(line, cmdptr);
    else if (start_chk(line) == 8)
      getcmd8(line, cmdptr);

    else {
      printf("Error: invalid input command line\n");
      continue;
    }


    nodelist = newnode(cmdptr);
    newtask->tids = execute(nodelist, NULL, NULL);
    if (newtask->tids != NULL) {
      jlist->job[jlist->n] = newtask;
      jlist->n++;
    }
    lwait(newtask->tids);

  }


  return 0;
}
Example #7
0
/*! Build the BVH, given an input data set
 *  - Handling our own stack is quite a bit faster than the recursive style.
 *  - Each build stack entry's parent field eventually stores the offset
 *    to the parent of that node. Before that is finally computed, it will
 *    equal exactly three other values. (These are the magic values Untouched,
 *    Untouched-1, and TouchedTwice).
 *  - The partition here was also slightly faster than std::partition.
 */
void BVH::build()
{
  BVHBuildEntry todo[128];
  uint32_t stackptr = 0;
  const uint32_t Untouched    = 0xffffffff;
  const uint32_t TouchedTwice = 0xfffffffd;

  // Push the root
  todo[stackptr].start = 0;
  todo[stackptr].end = build_prims->size();
  todo[stackptr].parent = 0xfffffffc;
  stackptr++;

  BVHFlatNode node;
  std::vector<BVHFlatNode> buildnodes;
  buildnodes.reserve(build_prims->size()*2);

  while(stackptr > 0) {
    // Pop the next item off of the stack
    BVHBuildEntry &bnode( todo[--stackptr] );
    uint32_t start = bnode.start;
    uint32_t end = bnode.end;
    uint32_t nPrims = end - start;

    nNodes++;
    node.start = start;
    node.nPrims = nPrims;
    node.rightOffset = Untouched;

    // Calculate the bounding box for this node
    BBox bb( (*build_prims)[start]->getBBox());
    BBox bc( (*build_prims)[start]->getCentroid());
    for(uint32_t p = start+1; p < end; ++p) {
      bb.expandToInclude( (*build_prims)[p]->getBBox());
      bc.expandToInclude( (*build_prims)[p]->getCentroid());
    }
    node.bbox = bb;

    // If the number of primitives at this point is less than the leaf
    // size, then this will become a leaf. (Signified by rightOffset == 0)
    if(nPrims <= leafSize) {
      node.rightOffset = 0;
      nLeafs++;
    }

    buildnodes.push_back(node);

    // Child touches parent...
    // Special case: Don't do this for the root.
    if(bnode.parent != 0xfffffffc) {
      buildnodes[bnode.parent].rightOffset --;

      // When this is the second touch, this is the right child.
      // The right child sets up the offset for the flat tree.
      if( buildnodes[bnode.parent].rightOffset == TouchedTwice ) {
        buildnodes[bnode.parent].rightOffset = nNodes - 1 - bnode.parent;
      }
    }

    // If this is a leaf, no need to subdivide.
    if(node.rightOffset == 0)
      continue;

    // Set the split dimensions
    uint32_t split_dim = bc.maxDimension();

    // Split on the center of the longest axis
    float split_coord = .5f * (bc.min[split_dim] + bc.max[split_dim]);

    // Partition the list of objects on this split
    uint32_t mid = start;
    for(uint32_t i=start;i<end;++i) {
      if( (*build_prims)[i]->getCentroid()[split_dim] < split_coord ) {
        std::swap( (*build_prims)[i], (*build_prims)[mid] );
        ++mid;
      }
    }

    // If we get a bad split, just choose the center...
    if(mid == start || mid == end) {
      mid = start + (end-start)/2;
    }

    // Push right child
    todo[stackptr].start = mid;
    todo[stackptr].end = end;
    todo[stackptr].parent = nNodes-1;
    stackptr++;

    // Push left child
    todo[stackptr].start = start;
    todo[stackptr].end = mid;
    todo[stackptr].parent = nNodes-1;
    stackptr++;
  }

  // Copy the temp node data to a flat array
  flatTree = new BVHFlatNode[nNodes];
  for(uint32_t n=0; n<nNodes; ++n) 
    flatTree[n] = buildnodes[n];
}
Example #8
0
void TestBufferingNode(const char * name) {
    tbb::flow::graph g;
    B                bnode(g);
    tbb::flow::function_node<int,int,tbb::flow::rejecting> fnode(g, tbb::flow::serial, serial_fn_body<int>(serial_fn_state0));
    REMARK("Testing %s:", name);
    for(int icnt = 0; icnt < 2; icnt++) {
        bool reverse_edge = (icnt & 0x2) != 0;
        serial_fn_state0 = 0;  // reset to waiting state.
        REMARK(" make_edge");
        tbb::flow::make_edge(bnode, fnode);
        ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after make_edge");
        REMARK(" try_put");
        bnode.try_put(1);  // will forward to the fnode
        BACKOFF_WAIT(serial_fn_state0 == 0, "Timed out waiting for first put");
        if(reverse_edge) {
            REMARK(" try_put2");
            bnode.try_put(2);  // will reverse the edge
            // cannot do a wait_for_all here; the function_node is still executing
            BACKOFF_WAIT(!bnode.my_successors.empty(), "Timed out waiting after 2nd put");
            // at this point the only task running is the one for the function_node.
            ASSERT(bnode.my_successors.empty(), "successor not removed");
        }
        else {
            ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after forwarding message");
        }
        serial_fn_state0 = 0;  // release the function_node.
        if(reverse_edge) {
            // have to do a second release because the function_node will get the 2nd item
            BACKOFF_WAIT( serial_fn_state0 == 0, "Timed out waiting after 2nd put");
            serial_fn_state0 = 0;  // release the function_node.
        }
        g.wait_for_all();
        REMARK(" remove_edge");
        tbb::flow::remove_edge(bnode, fnode);
        ASSERT(bnode.my_successors.empty(), "buffering node has a successor after remove_edge");
    }
    tbb::flow::join_node<tbb::flow::tuple<int,int>,tbb::flow::reserving> jnode(g);
    tbb::flow::make_edge(bnode, tbb::flow::input_port<0>(jnode));  // will spawn a task
    g.wait_for_all();
    ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after attaching to join");
    REMARK(" reverse");
    bnode.try_put(1);  // the edge should reverse
    g.wait_for_all();
    ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reserving");
    REMARK(" reset()");
    g.wait_for_all();
    g.reset();  // should be in forward direction again
    ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after reset()");
    REMARK(" remove_edge");
    g.reset(tbb::flow::rf_clear_edges);
    ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reset(rf_clear_edges)");
    tbb::flow::make_edge(bnode, tbb::flow::input_port<0>(jnode));  // add edge again
    // reverse edge by adding to buffer.
    bnode.try_put(1);  // the edge should reverse
    g.wait_for_all();
    ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reserving");
    REMARK(" remove_edge(reversed)");
    g.reset(tbb::flow::rf_clear_edges);
    ASSERT(bnode.my_successors.empty(), "buffering node has no successor after reset()");
    ASSERT(tbb::flow::input_port<0>(jnode).my_predecessors.empty(), "predecessor not reset");
    REMARK("  done\n");
    g.wait_for_all();
}