コード例 #1
0
ファイル: trace-builder.cpp プロジェクト: IMGM/hiphop-php
/*
 * reoptimize() runs a trace through a second pass of TraceBuilder
 * optimizations, like this:
 *
 *   reset state.
 *   move all blocks to a temporary list.
 *   compute immediate dominators.
 *   for each block in trace order:
 *     if we have a snapshot state for this block:
 *       clear cse entries that don't dominate this block.
 *       use snapshot state.
 *     move all instructions to a temporary list.
 *     for each instruction:
 *       optimizeWork - do CSE and simplify again
 *       if not simplified:
 *         append existing instruction and update state.
 *       else:
 *         if the instruction has a result, insert a mov from the
 *         simplified tmp to the original tmp and discard the instruction.
 *     if the last conditional branch was turned into a jump, remove the
 *     fall-through edge to the next block.
 */
void TraceBuilder::reoptimize() {
  FTRACE(5, "ReOptimize:vvvvvvvvvvvvvvvvvvvv\n");
  SCOPE_EXIT { FTRACE(5, "ReOptimize:^^^^^^^^^^^^^^^^^^^^\n"); };
  assert(m_curTrace == m_mainTrace.get());
  assert(m_savedTraces.size() == 0);

  m_enableCse = RuntimeOption::EvalHHIRCse;
  m_enableSimplification = RuntimeOption::EvalHHIRSimplification;
  if (!m_enableCse && !m_enableSimplification) return;
  if (m_mainTrace->blocks().size() >
      RuntimeOption::EvalHHIRSimplificationMaxBlocks) {
    // TODO CSEHash::filter is very slow for large block sizes
    // t2135219 should address that
    return;
  }

  BlockList sortedBlocks = rpoSortCfg(m_mainTrace.get(), m_irFactory);
  auto const idoms = findDominators(sortedBlocks);
  clearTrackedState();

  auto blocks = std::move(m_mainTrace->blocks());
  assert(m_mainTrace->blocks().empty());
  while (!blocks.empty()) {
    Block* block = blocks.front();
    blocks.pop_front();
    assert(block->trace() == m_mainTrace.get());
    FTRACE(5, "Block: {}\n", block->id());

    m_mainTrace->push_back(block);
    if (m_snapshots[block]) {
      useState(block);
    }

    auto instructions = std::move(block->instrs());
    assert(block->empty());
    while (!instructions.empty()) {
      auto *inst = &instructions.front();
      instructions.pop_front();

      // merging state looks at the current marker, and optimizeWork
      // below may create new instructions. Use the marker from this
      // instruction.
      assert(inst->marker().valid());
      setMarker(inst->marker());

      auto const tmp = optimizeWork(inst, idoms); // Can generate new instrs!
      if (!tmp) {
        // Could not optimize; keep the old instruction
        appendInstruction(inst, block);
        updateTrackedState(inst);
        continue;
      }
      SSATmp* dst = inst->dst();
      if (dst->type() != Type::None && dst != tmp) {
        // The result of optimization has a different destination than the inst.
        // Generate a mov(tmp->dst) to get result into dst. If we get here then
        // assume the last instruction in the block isn't a guard. If it was,
        // we would have to insert the mov on the fall-through edge.
        assert(block->empty() || !block->back()->isBlockEnd());
        IRInstruction* mov = m_irFactory.mov(dst, tmp, inst->marker());
        appendInstruction(mov, block);
        updateTrackedState(mov);
      }
      // Not re-adding inst; remove the inst->taken edge
      if (inst->taken()) inst->setTaken(nullptr);
    }
    if (block->back()->isTerminal()) {
      // Could have converted a conditional branch to Jmp; clear next.
      block->setNext(nullptr);
    } else {
      // if the last instruction was a branch, we already saved state
      // for the target in updateTrackedState().  Now save state for
      // the fall-through path.
      saveState(block->next());
    }
  }
}
コード例 #2
0
int main(int argc, char* argv[])
{
  title("Demonstrate Path Class");

  std::string fs = Path::fileSpec(".","temp.txt");
  std::cout << "\n  Path::fileSpec(\".\",\"temp.txt\") = " << fs;

  std::string path = Path::getPath(fs);
  std::cout << "\n  Path::getPath(\"" + fs + "\") = " << path;
  
  std::string ffs = Path::getFullFileSpec(fs);
  std::cout << "\n  Path::getFullFileSpec(\"" + fs + "\") = " << ffs;
  
  std::string name = Path::getName(fs);
  std::cout << "\n  Path::getName(\"" + fs + "\") = " << name;

  std::string ext = Path::getExt(fs);
  std::cout << "\n  Path::getExt(\"" + fs + "\") = " << ext;

  std::string upper = Path::toUpper("temp.txt");
  std::cout << "\n  Path::toUpper(\"temp.txt\") = " << upper;

  std::string lower = Path::toLower("Temp.Txt");
  std::cout << "\n  Path::toLower(\"Temp.Txt\") = " << lower;
  std::cout << std::endl;
  /*
  title("Demonstrate FileSystemSearch class");

  const size_t PathSetSize = 2;
  std::string home = ::getenv("HOMEDRIVE");
  std::string pathSet[] = { home+"\\\\", "." };
  FileSystemSearch fss;
  for(size_t i = 0; i<PathSetSize; ++i)
  {
    std::cout << "\n  searching for files on \"" << pathSet[i] << "\"";
    std::cout << "\n " << std::string(27 + pathSet[i].size(), '-');
    std::string searchPath = pathSet[i];
    std::string fileName = fss.firstFile(searchPath);
    if(fileName.size() > 0)
      std::cout << "\n  " << fileName;
    else
      std::cout << "\n  no files match search";
    while(true) {
      fileName = fss.nextFile();
      if(fileName.size() > 0)
        std::cout << "\n  " << fileName;
      else
        break;
    }
    std::cout << std::endl;

    std::cout << "\n  searching for directories on \"" << pathSet[i] << "\"";
    std::cout << "\n " << std::string(33 + pathSet[i].size(), '-');
    std::string dirName = fss.firstDirectory(searchPath);
    if(dirName.size() > 0)
      std::cout << "\n  " << dirName;
    else
      std::cout << "\n  no directories match search";
    while(true)
    {
      dirName = fss.nextDirectory();
      if(dirName.size() > 0)
        std::cout << "\n  " << dirName;
      else
        break;
    }
    std::cout << std::endl;
  }
  */
  title("Demonstrate Directory class");

  // Display contents of current directory

  std::cout << "\n  current directory is:\n    " << Directory::getCurrentDirectory();
  std::cout << "\n  It contains files:";
  std::vector<std::string> currfiles = Directory::getFiles();
  ///////////////////////////////////////////////////////
  // This works too
  // std::vector<std::string> currfiles = d.getFiles();  
  for(size_t i=0; i<currfiles.size(); ++i)
    std::cout << "\n    " << currfiles[i].c_str();
  std::cout << "\n  and contains directories:";
  std::vector<std::string> currdirs = Directory::getDirectories();
  for(size_t i=0; i<currdirs.size(); ++i)
    std::cout << "\n    " << currdirs[i].c_str();
  std::cout << "\n";

  // Display contents of non-current directory

  std::cout << "\n  .txt files residing in C:/temp are:";
  currfiles = Directory::getFiles("c:/temp/", "*.txt");
  for(size_t i=0; i<currfiles.size(); ++i)
    std::cout << "\n    " << currfiles[i].c_str();
  std::cout << "\n";
  std::cout << "\n  directories residing in C:/temp are:";
  currdirs = Directory::getDirectories("c:/temp/");
  for(size_t i=0; i<currdirs.size(); ++i)
    std::cout << "\n    " << currdirs[i].c_str();
  std::cout << "\n";

  // Create directory

  title("Demonstrate FileInfo Class Operations", '=');
  std::cout << "\n";

  Directory::setCurrentDirectory(".");
  std::cout << "\n  current path is \"" << Directory::getCurrentDirectory();
  
  std::string fn1;
  if(argc > 1)
    fn1 = argv[1];
  else
    fn1 = "c:\\temp\\test.txt";
  FileInfo fi(fn1);

  if(fi.good())
  {
    std::cout << "\n  name: " << "\t" << fi.name();
    std::cout << "\n  date: " << "\t" << fi.date();
    std::cout << "\n  date: " << "\t" << fi.date(FileInfo::dateformat);
    std::cout << "\n  date: " << "\t" << fi.date(FileInfo::timeformat);
    std::cout << "\n  size: " << "\t" << fi.size() << " bytes";
    if(fi.isArchive())
      std::cout << "\n  is archive";
    else
      std::cout << "\n  is not archive";
    if(fi.isCompressed())
      std::cout << "\n  is compressed";
    else
      std::cout << "\n  is not compressed";
    if(fi.isDirectory())
      std::cout << "\n  is directory";
    else
      std::cout << "\n  is not directory";
    if(fi.isEncrypted())
      std::cout << "\n  is encrypted";
    else
      std::cout << "\n  is not encrypted";
    if(fi.isHidden())
      std::cout << "\n  is hidden";
    else
      std::cout << "\n  is not hidden";
    if(fi.isNormal())
      std::cout << "\n  is normal";
    else
      std::cout << "\n  is not normal";
    if(fi.isOffLine())
      std::cout << "\n  is offline";
    else
      std::cout << "\n  is not offline";
    if(fi.isReadOnly())
      std::cout << "\n  is readonly";
    else
      std::cout << "\n  is not readonly";
    if(fi.isSystem())
      std::cout << "\n  is system";
    else
      std::cout << "\n  is not system";
    if(fi.isTemporary())
      std::cout << "\n  is temporary";
    else
      std::cout << "\n  is not temporary";
  }
  else
    std::cout << "\n  filename " << fn1 << " is not valid in this context\n";

  std::string fn2;
  if(argc > 2)
  {
    fn1 = argv[1];
    fn2 = argv[2];
  }
  else
  {
    fn1 = "FileSystem.h";
    fn2 = "FileSystem.cpp";
  }
  FileInfo fi1(fn1);
  FileInfo fi2(fn2);
  if(fi1.good() && fi2.good())
  {
    if(fi1 == fi1)
      std::cout << "\n  " << fi1.name() << " == " << fi1.name();
    else
      std::cout << "\n  " << fi1.name() << " != " << fi1.name();
    if(fi1 < fi1)
      std::cout << "\n  " << fi1.name() << " < " << fi1.name();
    else
      std::cout << "\n  " << fi1.name() << " >= " << fi1.name();
    if(fi1 == fi2)
      std::cout << "\n  " << fi1.name() << " == " << fi2.name();
    else
      std::cout << "\n  " << fi1.name() << " != " << fi2.name();
    if(fi1 < fi2)
      std::cout << "\n  " << fi1.name() << " < " << fi2.name();
    else
      std::cout << "\n  " << fi1.name() << " >= " << fi2.name();
    if(fi1.smaller(fi2))
      std::cout << "\n  " << fi1.name() << " is smaller than " << fi2.name();
    else
      std::cout << "\n  " << fi1.name() << " is not smaller than " << fi2.name();
    if(fi1.earlier(fi2))
      std::cout << "\n  " << fi1.name() << " is earlier than " << fi2.name();
    else
      std::cout << "\n  " << fi1.name() << " is not earlier than " << fi2.name();
    std::cout << std::endl;
  }
  else
    std::cout << "\n  files " << fn1 << " and " << fn2 << " are not valid in this context\n";

  title("Demonstrate File class operations", '=');
  std::cout << "\n";

  // copy binary file from one directory to another

  File me("../debug/filesystemdemo.exe");
  me.open(File::in, File::binary);
  std::cout << "\n  copying " << me.name().c_str() << " to c:/temp";
  if(!me.isGood())
  {
    std::cout << "\n  can't open executable\n";
    std::cout << "\n  looking for:\n  ";
    std::cout << Path::getFullFileSpec(me.name()) << "\n";
  }
  else
  {
    File you("c:/temp/fileSystemdemo.exe");
    you.open(File::out, File::binary);
    if(you.isGood())
    {
      while(me.isGood())
      {
        Block b = me.getBlock(1024);
        std::cout << "\n    reading block of " << b.size() << " bytes";
        you.putBlock(b);
        std::cout << "\n    writing block of " << b.size() << " bytes"; 
      }
      std::cout << "\n";
    }
  }

  // save some filespecs of text files in a vector for File demonstrations

  std::vector<std::string> files;
  if(argc == 1)
  {
    std::cout << "\n\n  Please enter, on the command line, a filename to process.\n";
  }

  for(int i=1; i<argc; ++i)
  {
    files.push_back(argv[i]);
  }
  files.push_back("FileSystem.cpp");
  files.push_back("../FileSystemDemo/FileSystem.cpp"); // file from project directory
  files.push_back("../test.txt");  // file in executable's debug directory
  files.push_back("foobar");             // doesn't exist

  // open each file and display a few lines of text

  for(size_t i=0; i<files.size(); ++i)
  {
    File file(files[i]);
    file.open(File::in);
    if(!file.isGood())
    {
      std::cout << "\n  Can't open file " << file.name();
      std::cout << "\n  Here's what the program can't find:\n  " << Path::getFullFileSpec(file.name()); 
      continue;
    }
    std::string temp = std::string("Processing file ") + files[i];
    title(temp, '-');
    for(int j=0; j<10; ++j)
    {
      if(!file.isGood())
        break;
      std::cout << "\n  " << file.getLine().c_str();
    }
    std::cout << "\n";
  }
  std::cout << "\n";

  // read text file and write to another text file

  title("writing to c:/temp/test.txt", '-');
  File in("../test.txt");
  in.open(File::in);
  File out("c:/temp/test.txt");
  out.open(File::out);
  while(in.isGood())
  {
    std::string temp = in.getLine();
    std::cout << "\n  " << temp.c_str();
    out.putLine(temp);
    out.putLine("\n");
  }
  std::cout << "\n\n";
}
コード例 #3
0
ファイル: b_plus_tree.cpp プロジェクト: AlecWong/DBSQL
void BPlusTree::_remove(Block blk, AttrType k) {
    Node node(blk);
    int i;
    
    std::cout << "BPlusTree::_remove == k " << k.datai << std::endl;
    std::cout << "BPlusTree::_remove == blk.pos " << blk.pos << std::endl;
    
    // delete the corresponding p, k at first
    for( i = 0; i < node.getKSize(); i++ ) {
        if( node.getK(i) == k ) {
            node.remove(k, node.getP(i), i);
            break;
        }
    }
    
    // then check whether the size of the node is too small
    bool isRootWithSoleChild =  node.isRoot() && !node.isLeaf() && node.getPSize() == 1;
    
    bool isNotRootAndTooSmall = ( node.isLeaf() && node.getKSize() < fanout / 2 ) || ( !node.isLeaf() && node.getKSize() < (fanout+1) / 2 );
    
    isNotRootAndTooSmall = isNotRootAndTooSmall && node.isRoot();
    
    
    if( isRootWithSoleChild ) { // If the root node has only one pointer after deletion, it is deleted and the sole child becomes the root.
        Block soleChildBlk;
        bufferManager->getBlock(filename, node.getP(0), soleChildBlk);
        Node soleChildNode(soleChildBlk);
        soleChildNode.setRoot(true);
        setRootNode(soleChildNode);
        setRootPos(soleChildBlk.getPos());
        soleChildNode.write2Blk(soleChildBlk, typeId, strLen, bufferManager);
        bufferManager->deleteBlock(blk);
        
        return;
    }
    else if( isNotRootAndTooSmall ) {
        Block parentBlk;
        Block siblingBlk;
        Node siblingNode;
        AttrType nk;
        
        std::cout << "isNotRootAndTooSmall" << std::endl;
        
        std::cout << "stk.top() = " << stk.top() << std::endl;
        
        stk.pop();
        
        std::cout << "parentBlk pos = " << stk.size() << std::endl;
        
        bufferManager->getBlock(filename, stk.top(), parentBlk);
        //stk.pop();
        Node parentNode(parentBlk);
        
        std::cout << "f**k" << std::endl;
        
        // find sibling
        bool isLeftSibling = true;
        int siblingPos;
        
        for( i = 0; i < parentNode.getPSize(); i++ ) {
            if( parentNode.getP(i) == blk.getPos() ) {
                if( i > 0 ) {
                    siblingPos = parentNode.getP(i-1);
                    nk = parentNode.getK(i);
                }
                else {
                    siblingPos = parentNode.getP(i+1);
                    nk = parentNode.getK(i);
                    isLeftSibling = false;
                }
                
                std::cout << "siblingPos " << siblingPos/BLOCK_SIZE << std::endl;
                
                bufferManager->getBlock(filename, siblingPos, siblingBlk);
                siblingNode.resetByBlock(siblingBlk);
                break;
            }
        }
        
        std::cout << "success up to now" << std::endl;
        
        
        
        // merge
        if( !isLeftSibling ) {
            std::swap(node, siblingNode);
            std::swap(blk, siblingBlk);
        }
        
        if( siblingNode.isLeaf() ) {
            siblingNode.popP();
        }
        else {
            siblingNode.appendK(nk);
        }
        
        for( i = 0; i < node.getPSize(); i++ ) {
            siblingNode.appendP(node.getP(i));
            if( i < node.getPSize() - 1 ) {
                siblingNode.appendK(node.getK(i));
            }
        }
        
        for( i = 0; i < siblingNode.getPSize(); i++ ) {
            std::cout << "siblingNode.getP[" << i << "] = " << siblingNode.getP(i) << std::endl;
        }
        
        for( i = 0; i < siblingNode.getKSize(); i++ ) {
            std::cout << "siblingNode.getK[" << i << "] = " << siblingNode.getK(i).datai << std::endl;
        }
        
        if( siblingNode.getPSize() <= fanout ) { // can be merged
            std::cout << "siblingNode.write2Blk -- siblingBlk.pos[] " << siblingBlk.pos << std::endl;
            
            
            
            // siblingNode.write2Blk(siblingBlk, typeId, strLen, bufferManager);
            // bufferManager->deleteBlock(blk);
            siblingNode.write2Blk(blk, typeId, strLen, bufferManager);
            bufferManager->deleteBlock(siblingBlk);
            
            
            _remove(parentBlk, nk);
        }
        else { // split
            Node n1(false, false), n2(false, false);
            
            for( i = 0; i < (siblingNode.getPSize() + 1) / 2 - 1; i++ ) {
                n1.appendK(siblingNode.getK(i));
                n1.appendP(siblingNode.getP(i));
            }
            
            n1.appendP(siblingNode.getP(i));
            for( i = (siblingNode.getPSize() + 1) / 2; i < (siblingNode.getPSize() + 1) / 2; i++ ) {
                n2.appendK(siblingNode.getK(i));
                n2.appendP(siblingNode.getP(i));
            }
            
            n2.appendP(siblingNode.getP(i));
            
            n1.write2Blk(siblingBlk, typeId, strLen, bufferManager);
            n2.write2Blk(blk, typeId, strLen, bufferManager);
            
            if( !isLeftSibling ) {
                std::swap(blk, siblingBlk);
            }
        }
    }
    else {
        node.write2Blk(blk, typeId, strLen, bufferManager);
    }
}
コード例 #4
0
int DynamicTransferBufferManagerEntry::write(unsigned offset, const uint8_t* data, unsigned len)
{
    if (!data)
    {
        assert(0);
        return -ErrInvalidParam;
    }

    if (offset >= max_size_)
    {
        return 0;
    }
    if ((offset + len) > max_size_)
    {
        len = max_size_ - offset;
    }
    assert((offset + len) <= max_size_);

    unsigned total_offset = 0;
    unsigned left_to_write = len;
    const uint8_t* inptr = data;
    Block* p = blocks_.get();
    Block* last_written_block = NULL;

    // First we need to write the part that is already allocated
    while (p)
    {
        last_written_block = p;
        p->write(inptr, offset, total_offset, left_to_write);
        if (left_to_write == 0)
        {
            break;
        }
        p = p->getNextListNode();
    }

    // Then we need to append new chunks until all data is written
    while (left_to_write > 0)
    {
        // cppcheck-suppress nullPointer
        assert(p == NULL);

        // Allocating the chunk
        Block* new_block = Block::instantiate(allocator_);
        if (new_block == NULL)
        {
            break;                        // We're in deep shit.
        }
        // Appending the chain with the new block
        if (last_written_block != NULL)
        {
            assert(last_written_block->getNextListNode() == NULL);  // Because it is last in the chain
            last_written_block->setNextListNode(new_block);
            new_block->setNextListNode(NULL);
        }
        else
        {
            blocks_.insert(new_block);
        }
        last_written_block = new_block;

        // Writing the data
        new_block->write(inptr, offset, total_offset, left_to_write);
    }

    const int actually_written = len - left_to_write;
    max_write_pos_ = max(offset + actually_written, unsigned(max_write_pos_));
    return actually_written;
}
コード例 #5
0
ファイル: lcm.cpp プロジェクト: AllenWeb/openjdk-1
//------------------------------call_catch_cleanup-----------------------------
// If we inserted any instructions between a Call and his CatchNode,
// clone the instructions on all paths below the Catch.
void Block::call_catch_cleanup(Block_Array &bbs) {

  // End of region to clone
  uint end = end_idx();
  if( !_nodes[end]->is_Catch() ) return;
  // Start of region to clone
  uint beg = end;
  while( _nodes[beg-1]->Opcode() != Op_MachProj ||
        !_nodes[beg-1]->in(0)->is_Call() ) {
    beg--;
    assert(beg > 0,"Catch cleanup walking beyond block boundary");
  }
  // Range of inserted instructions is [beg, end)
  if( beg == end ) return;

  // Clone along all Catch output paths.  Clone area between the 'beg' and
  // 'end' indices.
  for( uint i = 0; i < _num_succs; i++ ) {
    Block *sb = _succs[i];
    // Clone the entire area; ignoring the edge fixup for now.
    for( uint j = end; j > beg; j-- ) {
      Node *clone = _nodes[j-1]->clone();
      sb->_nodes.insert( 1, clone );
      bbs.map(clone->_idx,sb);
    }
  }


  // Fixup edges.  Check the def-use info per cloned Node
  for(uint i2 = beg; i2 < end; i2++ ) {
    uint n_clone_idx = i2-beg+1; // Index of clone of n in each successor block
    Node *n = _nodes[i2];        // Node that got cloned
    // Need DU safe iterator because of edge manipulation in calls.
    Unique_Node_List *out = new Unique_Node_List(Thread::current()->resource_area());
    for (DUIterator_Fast j1max, j1 = n->fast_outs(j1max); j1 < j1max; j1++) {
      out->push(n->fast_out(j1));
    }
    uint max = out->size();
    for (uint j = 0; j < max; j++) {// For all users
      Node *use = out->pop();
      Block *buse = bbs[use->_idx];
      if( use->is_Phi() ) {
        for( uint k = 1; k < use->req(); k++ )
          if( use->in(k) == n ) {
            Node *fixup = catch_cleanup_find_cloned_def(bbs[buse->pred(k)->_idx], n, this, bbs, n_clone_idx);
            use->set_req(k, fixup);
          }
      } else {
        if (this == buse) {
          catch_cleanup_intra_block(use, n, this, beg, n_clone_idx);
        } else {
          catch_cleanup_inter_block(use, buse, n, this, bbs, n_clone_idx);
        }
      }
    } // End for all users

  } // End of for all Nodes in cloned area

  // Remove the now-dead cloned ops
  for(uint i3 = beg; i3 < end; i3++ ) {
    _nodes[beg]->disconnect_inputs(NULL);
    _nodes.remove(beg);
  }

  // If the successor blocks have a CreateEx node, move it back to the top
  for(uint i4 = 0; i4 < _num_succs; i4++ ) {
    Block *sb = _succs[i4];
    uint new_cnt = end - beg;
    // Remove any newly created, but dead, nodes.
    for( uint j = new_cnt; j > 0; j-- ) {
      Node *n = sb->_nodes[j];
      if (n->outcnt() == 0 &&
          (!n->is_Proj() || n->as_Proj()->in(0)->outcnt() == 1) ){
        n->disconnect_inputs(NULL);
        sb->_nodes.remove(j);
        new_cnt--;
      }
    }
    // If any newly created nodes remain, move the CreateEx node to the top
    if (new_cnt > 0) {
      Node *cex = sb->_nodes[1+new_cnt];
      if( cex->is_Mach() && cex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
        sb->_nodes.remove(1+new_cnt);
        sb->_nodes.insert(1,cex);
      }
    }
  }
}
コード例 #6
0
void NativeBlockOutputStream::write(const Block & block)
{
    /// Additional information about the block.
    if (client_revision > 0)
        block.info.write(ostr);

    block.checkNumberOfRows();

    /// Dimensions
    size_t columns = block.columns();
    size_t rows = block.rows();

    writeVarUInt(columns, ostr);
    writeVarUInt(rows, ostr);

    /** The index has the same structure as the data stream.
      * But instead of column values, it contains a mark that points to the location in the data file where this part of the column is located.
      */
    if (index_ostr)
    {
        writeVarUInt(columns, *index_ostr);
        writeVarUInt(rows, *index_ostr);
    }

    for (size_t i = 0; i < columns; ++i)
    {
        /// For the index.
        MarkInCompressedFile mark;

        if (index_ostr)
        {
            ostr_concrete->next();  /// Finish compressed block.
            mark.offset_in_compressed_file = initial_size_of_file + ostr_concrete->getCompressedBytes();
            mark.offset_in_decompressed_block = ostr_concrete->getRemainingBytes();
        }

        const ColumnWithTypeAndName & column = block.safeGetByPosition(i);

        /// Name
        writeStringBinary(column.name, ostr);

        /// Type
        String type_name = column.type->getName();

        /// For compatibility, we will not send explicit timezone parameter in DateTime data type
        ///  to older clients, that cannot understand it.
        if (client_revision < DBMS_MIN_REVISION_WITH_TIME_ZONE_PARAMETER_IN_DATETIME_DATA_TYPE
            && startsWith(type_name, "DateTime("))
            type_name = "DateTime";

        writeStringBinary(type_name, ostr);

        /// Data
        if (rows)    /// Zero items of data is always represented as zero number of bytes.
            writeData(*column.type, column.column, ostr, 0, 0);

        if (index_ostr)
        {
            writeStringBinary(column.name, *index_ostr);
            writeStringBinary(column.type->getName(), *index_ostr);

            writeBinary(mark.offset_in_compressed_file, *index_ostr);
            writeBinary(mark.offset_in_decompressed_block, *index_ostr);
        }
    }
}
コード例 #7
0
ファイル: point.C プロジェクト: pamoakoy/daisy-model
XYPoint::XYPoint (const Block& al)
  : x (al.number ("x")),
    y (al.number ("y"))
{ }
コード例 #8
0
ファイル: librarian.C プロジェクト: perabrahamsen/daisy-model
void 
Librarian::non_null (const Block& block, const void *const p)
{ 
  if (!p)
    block.error ("Build failed");
}
コード例 #9
0
ファイル: heap.cpp プロジェクト: itavero/openthread
void Heap::Free(void *aPointer)
{
    if (aPointer == NULL)
    {
        return;
    }

    Block &block = BlockOf(aPointer);
    Block &right = BlockRight(block);

    if (IsLeftFree(block))
    {
        Block *prev = &BlockSuper();
        Block *left = &BlockNext(*prev);

        for (const uint16_t offset = block.GetLeftNext(); left->GetNext() != offset; left = &BlockNext(*left))
        {
            prev = left;
        }

        // Remove left from free list.
        prev->SetNext(left->GetNext());
        left->SetNext(0);

        if (right.IsFree())
        {
            if (right.GetSize() > left->GetSize())
            {
                for (const uint16_t offset = BlockOffset(right); prev->GetNext() != offset; prev = &BlockNext(*prev))
                    ;
            }
            else
            {
                prev = &BlockPrev(right);
            }

            // Remove right from free list.
            prev->SetNext(right.GetNext());
            right.SetNext(0);

            // Add size of right.
            left->SetSize(left->GetSize() + right.GetSize() + sizeof(Block));
        }

        // Add size of current block.
        left->SetSize(left->GetSize() + block.GetSize() + sizeof(Block));

        BlockInsert(*prev, *left);
    }
    else
    {
        if (right.IsFree())
        {
            Block &prev = BlockPrev(right);
            prev.SetNext(right.GetNext());
            block.SetSize(block.GetSize() + right.GetSize() + sizeof(Block));
            BlockInsert(prev, block);
        }
        else
        {
            BlockInsert(BlockSuper(), block);
        }
    }
}
コード例 #10
0
void BlockManager::init()
{

    Block* grass = new Block("Grass");
    Side* dirtLook = new Side("../Resources/Dirt.jpg");
    Side* grassLook = new Side("../Resources/Grass.jpg");
    grass->setFront(dirtLook)
        ->setBack(dirtLook)
        ->setLeft(dirtLook)
        ->setRight(dirtLook)
        ->setBottom(dirtLook)
        ->setTop(grassLook)
        ->setSolid(true)
        ->setDurability(2);
    this->registerBlock("Grass", grass);

    Block* dirt = new Block("Dirt");

    dirt->setFront(dirtLook)
        ->setBack(dirtLook)
        ->setLeft(dirtLook)
        ->setRight(dirtLook)
        ->setBottom(dirtLook)
        ->setTop(dirtLook)
        ->setSolid(true)
        ->setDurability(2);
    this->registerBlock("Dirt", dirt);

    Block* stone = new Block("Stone");
    Side* stoneLook = new Side("../Resources/Stone.jpg");
    dirt->setFront(dirtLook)
        ->setBack(stoneLook)
        ->setLeft(stoneLook)
        ->setRight(stoneLook)
        ->setBottom(stoneLook)
        ->setTop(stoneLook)
        ->setSolid(true)
        ->setDurability(10);
    this->registerBlock("Stone", stone);

    Block* air = new Block("Air");
    air->setSolid(false);
    this->registerBlock("Air", air);

    Block* mantle = new Block("Mantle");
    Side* mantleLook = new Side("../Resources/Mantle.jpg");
    mantle->setFront(mantleLook)
        ->setBack(mantleLook)
        ->setLeft(mantleLook)
        ->setRight(mantleLook)
        ->setBottom(mantleLook)
        ->setTop(mantleLook)
        ->setSolid(true)
        ->setDurability(1000);
    this->registerBlock("Mantle", mantle);

    delete grassLook;
    delete dirtLook;
    delete stoneLook;
    delete mantleLook;
}
コード例 #11
0
void ExecuteScalarSubqueriesMatcher::visit(const ASTSubquery & subquery, ASTPtr & ast, Data & data)
{
    Context subquery_context = data.context;
    Settings subquery_settings = data.context.getSettings();
    subquery_settings.max_result_rows = 1;
    subquery_settings.extremes = 0;
    subquery_context.setSettings(subquery_settings);

    ASTPtr subquery_select = subquery.children.at(0);
    BlockIO res = InterpreterSelectWithUnionQuery(
        subquery_select, subquery_context, {}, QueryProcessingStage::Complete, data.subquery_depth + 1).execute();

    Block block;
    try
    {
        block = res.in->read();

        if (!block)
        {
            /// Interpret subquery with empty result as Null literal
            auto ast_new = std::make_unique<ASTLiteral>(Null());
            ast_new->setAlias(ast->tryGetAlias());
            ast = std::move(ast_new);
            return;
        }

        if (block.rows() != 1 || res.in->read())
            throw Exception("Scalar subquery returned more than one row", ErrorCodes::INCORRECT_RESULT_OF_SCALAR_SUBQUERY);
    }
    catch (const Exception & e)
    {
        if (e.code() == ErrorCodes::TOO_MANY_ROWS)
            throw Exception("Scalar subquery returned more than one row", ErrorCodes::INCORRECT_RESULT_OF_SCALAR_SUBQUERY);
        else
            throw;
    }

    size_t columns = block.columns();
    if (columns == 1)
    {
        auto lit = std::make_unique<ASTLiteral>((*block.safeGetByPosition(0).column)[0]);
        lit->alias = subquery.alias;
        lit->prefer_alias_to_column_name = subquery.prefer_alias_to_column_name;
        ast = addTypeConversion(std::move(lit), block.safeGetByPosition(0).type->getName());
    }
    else
    {
        auto tuple = std::make_shared<ASTFunction>();
        tuple->alias = subquery.alias;
        ast = tuple;
        tuple->name = "tuple";
        auto exp_list = std::make_shared<ASTExpressionList>();
        tuple->arguments = exp_list;
        tuple->children.push_back(tuple->arguments);

        exp_list->children.resize(columns);
        for (size_t i = 0; i < columns; ++i)
        {
            exp_list->children[i] = addTypeConversion(
                std::make_unique<ASTLiteral>((*block.safeGetByPosition(i).column)[0]),
                block.safeGetByPosition(i).type->getName());
        }
    }
}
コード例 #12
0
void ArkanoidRemakeSdl::HitBlock(Block& block, int x, int y)
{
  ArkanoidRemake::HitBlock(block, x, y);
  PlaySound( block.Visible() ? "brickhit" : "brickdestroy" );
}
コード例 #13
0
ファイル: region-selection.cpp プロジェクト: guns2410/hhvm
RegionDescPtr selectTraceletLegacy(Offset initSpOffset,
                                   const Tracelet& tlet) {
  typedef RegionDesc::Block Block;

  auto const region = std::make_shared<RegionDesc>();
  SrcKey sk(tlet.m_sk);
  auto const unit = tlet.func()->unit();

  const Func* topFunc = nullptr;
  Block* curBlock = nullptr;
  auto newBlock = [&](SrcKey start, Offset spOff) {
    assert(curBlock == nullptr || curBlock->length() > 0);
    region->blocks.push_back(
      std::make_shared<Block>(
        start.func(), start.resumed(), start.offset(), 0, spOff));
    Block* newCurBlock = region->blocks.back().get();
    if (curBlock) {
      region->addArc(curBlock->id(), newCurBlock->id());
    }
    curBlock = newCurBlock;
  };
  newBlock(sk, initSpOffset);

  for (auto ni = tlet.m_instrStream.first; ni; ni = ni->next) {
    assert(sk == ni->source);
    assert(ni->unit() == unit);

    Offset curSpOffset = initSpOffset + ni->stackOffset;

    curBlock->addInstruction();
    if ((curBlock->length() == 1 && ni->funcd != nullptr) ||
        ni->funcd != topFunc) {
      topFunc = ni->funcd;
      curBlock->setKnownFunc(sk, topFunc);
    }

    if (ni->calleeTrace && !ni->calleeTrace->m_inliningFailed) {
      assert(ni->op() == Op::FCall || ni->op() == Op::FCallD);
      assert(ni->funcd == ni->calleeTrace->func());
      // This should be translated as an inlined call. Insert the blocks of the
      // callee in the region.
      auto const& callee = *ni->calleeTrace;
      curBlock->setInlinedCallee(ni->funcd);
      SrcKey cSk = callee.m_sk;
      auto const cUnit = callee.func()->unit();

      // Note: the offsets of the inlined blocks aren't currently read
      // for anything, so it's unclear whether they should be relative
      // to the main function entry or the inlined function.  We're
      // just doing this for now.
      auto const initInliningSpOffset = curSpOffset;
      newBlock(cSk,
               initInliningSpOffset + callee.m_instrStream.first->stackOffset);

      for (auto cni = callee.m_instrStream.first; cni; cni = cni->next) {
        // Sometimes inlined callees trace through jumps that have a
        // known taken/non-taken state based on the calling context:
        if (cni->nextOffset != kInvalidOffset) {
          curBlock->addInstruction();
          cSk.setOffset(cni->nextOffset);
          newBlock(cSk, initInliningSpOffset + ni->stackOffset);
          continue;
        }

        assert(cSk == cni->source);
        assert(cni->op() == OpRetC ||
               cni->op() == OpRetV ||
               cni->op() == OpCreateCont ||
               cni->op() == OpAwait ||
               cni->op() == OpNativeImpl ||
               !instrIsNonCallControlFlow(cni->op()));

        curBlock->addInstruction();
        cSk.advance(cUnit);
      }

      if (ni->next) {
        sk.advance(unit);
        newBlock(sk, curSpOffset);
      }
      continue;
    }

    if (!ni->noOp && isFPassStar(ni->op())) {
      curBlock->setParamByRef(sk, ni->preppedByRef);
    }

    if (ni->next && isUnconditionalJmp(ni->op())) {
      // A Jmp that isn't the final instruction in a Tracelet means we traced
      // through a forward jump in analyze. Update sk to point to the next NI
      // in the stream.
      auto dest = ni->offset() + ni->imm[0].u_BA;
      assert(dest > sk.offset()); // We only trace for forward Jmps for now.
      sk.setOffset(dest);

      // The Jmp terminates this block.
      newBlock(sk, curSpOffset);
    } else {
      sk.advance(unit);
    }
  }

  auto& frontBlock = *region->blocks.front();

  // Add tracelet guards as predictions on the first instruction. Predictions
  // and known types from static analysis will be applied by
  // Translator::translateRegion.
  for (auto const& dep : tlet.m_dependencies) {
    if (dep.second->rtt.isVagueValue() ||
        dep.second->location.isThis()) continue;

    typedef RegionDesc R;
    auto addPred = [&](const R::Location& loc) {
      auto type = Type(dep.second->rtt);
      frontBlock.addPredicted(tlet.m_sk, {loc, type});
    };

    switch (dep.first.space) {
      case Location::Stack: {
        uint32_t offsetFromSp = uint32_t(-dep.first.offset - 1);
        uint32_t offsetFromFp = initSpOffset - offsetFromSp;
        addPred(R::Location::Stack{offsetFromSp, offsetFromFp});
        break;
      }
      case Location::Local:
        addPred(R::Location::Local{uint32_t(dep.first.offset)});
        break;

      default: not_reached();
    }
  }

  // Add reffiness dependencies as predictions on the first instruction.
  for (auto const& dep : tlet.m_refDeps.m_arMap) {
    RegionDesc::ReffinessPred pred{dep.second.m_mask,
                                   dep.second.m_vals,
                                   dep.first};
    frontBlock.addReffinessPred(tlet.m_sk, pred);
  }

  FTRACE(2, "Converted Tracelet:\n{}\nInto RegionDesc:\n{}\n",
         tlet.toString(), show(*region));
  return region;
}
コード例 #14
0
void
ControlParameters::wireDecode(const Block& block)
{
    if (block.type() != tlv::nfd::ControlParameters) {
        throw Error("expecting TLV-TYPE ControlParameters");
    }
    m_wire = block;
    m_wire.parse();
    Block::element_const_iterator val;

    val = m_wire.find(tlv::Name);
    m_hasFields[CONTROL_PARAMETER_NAME] = val != m_wire.elements_end();
    if (this->hasName()) {
        m_name.wireDecode(*val);
    }

    val = m_wire.find(tlv::nfd::FaceId);
    m_hasFields[CONTROL_PARAMETER_FACE_ID] = val != m_wire.elements_end();
    if (this->hasFaceId()) {
        m_faceId = static_cast<uint64_t>(readNonNegativeInteger(*val));
    }

    val = m_wire.find(tlv::nfd::Uri);
    m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
    if (this->hasUri()) {
        m_uri.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
    }

    val = m_wire.find(tlv::nfd::LocalControlFeature);
    m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = val != m_wire.elements_end();
    if (this->hasLocalControlFeature()) {
        m_localControlFeature = static_cast<LocalControlFeature>(readNonNegativeInteger(*val));
    }

    val = m_wire.find(tlv::nfd::Origin);
    m_hasFields[CONTROL_PARAMETER_ORIGIN] = val != m_wire.elements_end();
    if (this->hasOrigin()) {
        m_origin = static_cast<uint64_t>(readNonNegativeInteger(*val));
    }

    val = m_wire.find(tlv::nfd::Cost);
    m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
    if (this->hasCost()) {
        m_cost = static_cast<uint64_t>(readNonNegativeInteger(*val));
    }

    val = m_wire.find(tlv::nfd::Flags);
    m_hasFields[CONTROL_PARAMETER_FLAGS] = val != m_wire.elements_end();
    if (this->hasFlags()) {
        m_flags = static_cast<uint64_t>(readNonNegativeInteger(*val));
    }

    val = m_wire.find(tlv::nfd::Strategy);
    m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
    if (this->hasStrategy()) {
        val->parse();
        if (val->elements().empty()) {
            throw Error("expecting Strategy/Name");
        }
        else {
            m_strategy.wireDecode(*val->elements_begin());
        }
    }

    val = m_wire.find(tlv::nfd::ExpirationPeriod);
    m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = val != m_wire.elements_end();
    if (this->hasExpirationPeriod()) {
        m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
    }
}
コード例 #15
0
ファイル: output_nested.cpp プロジェクト: raimondfred/libsass
  void Output_Nested::operator()(Ruleset* r)
  {
    Selector* s     = r->selector();
    Block*    b     = r->block();
    bool      decls = false;

    // In case the extend visitor isn't called (if there are no @extend
    // directives in the entire document), check for placeholders here and
    // make sure they aren't output.
    // TODO: investigate why I decided to duplicate this logic in the extend visitor
    Selector_List* sl = static_cast<Selector_List*>(s);
    if (!ctx->extensions.size()) {
      Selector_List* new_sl = new (ctx->mem) Selector_List(sl->path(), sl->position());
      for (size_t i = 0, L = sl->length(); i < L; ++i) {
        if (!(*sl)[i]->has_placeholder()) {
          *new_sl << (*sl)[i];
        }
      }
      s = new_sl;
      sl = new_sl;
      r->selector(new_sl);
    }

    if (sl->length() == 0) return;

    if (b->has_non_hoistable()) {
      decls = true;
      indent();
      if (source_comments) {
        stringstream ss;
        ss << "/* line " << r->position().line << ", " << r->path() << " */" << endl;
        append_singleline_part_to_buffer(ss.str());
        indent();
      }
      s->perform(this);
      append_multiline_part_to_buffer(" {\n");
      ++indentation;
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        bool bPrintExpression = true;
        // Check print conditions
        if (typeid(*stm) == typeid(Declaration)) {
          Declaration* dec = static_cast<Declaration*>(stm);
          if (dec->value()->concrete_type() == Expression::STRING) {
            String_Constant* valConst = static_cast<String_Constant*>(dec->value());
            string val(valConst->value());
            if (val.empty()) {
              bPrintExpression = false;
            }
          }
          else if (dec->value()->concrete_type() == Expression::LIST) {
            List* list = static_cast<List*>(dec->value());
            bool all_invisible = true;
            for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) {
              Expression* item = (*list)[list_i];
              if (!item->is_invisible()) all_invisible = false;
            }
            if (all_invisible) bPrintExpression = false;
          }
        }
        // Print if OK
        if (!stm->is_hoistable() && bPrintExpression) {
          if (!stm->block()) indent();
          stm->perform(this);
          append_multiline_part_to_buffer("\n");
        }
      }
      --indentation;
      buffer.erase(buffer.length()-1);
      if (ctx) ctx->source_map.remove_line();
      append_multiline_part_to_buffer(" }\n");
    }

    if (b->has_hoistable()) {
      if (decls) ++indentation;
      // indent();
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (stm->is_hoistable()) {
          stm->perform(this);
        }
      }
      if (decls) --indentation;
    }
  }
コード例 #16
0
ファイル: heap.cpp プロジェクト: itavero/openthread
void *Heap::CAlloc(size_t aCount, size_t aSize)
{
    void *   ret  = NULL;
    Block *  prev = NULL;
    Block *  curr = NULL;
    uint16_t size = static_cast<uint16_t>(aCount * aSize);

    VerifyOrExit(size);

    size += kAlignSize - 1 - kBlockRemainderSize;
    size &= ~(kAlignSize - 1);
    size += kBlockRemainderSize;

    prev = &BlockSuper();
    curr = &BlockNext(*prev);

    while (curr->GetSize() < size)
    {
        prev = curr;
        curr = &BlockNext(*curr);
    }

    VerifyOrExit(curr->IsFree());

    prev->SetNext(curr->GetNext());

    if (curr->GetSize() > size + sizeof(Block))
    {
        const uint16_t newBlockSize = curr->GetSize() - size - sizeof(Block);
        curr->SetSize(size);

        Block &newBlock = BlockRight(*curr);
        newBlock.SetSize(newBlockSize);
        newBlock.SetNext(0);

        if (prev->GetSize() < newBlockSize)
        {
            BlockInsert(*prev, newBlock);
        }
        else
        {
            BlockInsert(BlockSuper(), newBlock);
        }
    }

    curr->SetNext(0);

    memset(curr->GetPointer(), 0, size);
    ret = curr->GetPointer();

exit:
    return ret;
}
コード例 #17
0
// calls each blocks renderToVBO function to create the VBO
bool VBOChunk::buildVBO(World &world, std::vector<Vertex> *vb, std::vector<TexVert> *tb, std::vector<ColVert> *cb,
                        std::vector<Vertex> *tvb, std::vector<TexVert> *ttb, std::vector<ColVert> *tcb)
{
    Block *block;

    vertBuffer = vb;
    texBuffer = tb;
    colBuffer = cb;

    transVertBuffer = tvb;
    transTexBuffer = ttb;
    transColBuffer = tcb;

    for(int xx = 0; xx < 16; xx++)
    {
        for(int yy = 0; yy < 16; yy++)
        {
            for(int zz = 0; zz < 16; zz++)
            {
                block = world.getBlock(xx + posx, yy + posy, zz + posz);
                if(block)
                    block->renderToVBO(world, *this, xx, yy, zz);
            }
        }
    }
    vertexCount = vertBuffer->size();
    transVertexCount = transVertBuffer->size();
    
    bool r = false;

    if(vertexCount > 0)
    {
        r = true;
        std::vector<Vertex>::iterator iter = vertBuffer->begin();
        glGenBuffersARB(1, &m_VBOverticies);                        // get a valid name
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_VBOverticies);       // bind the buffer
        // load the data
        glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertBuffer->size()*3*sizeof(float), &(*iter), GL_STATIC_DRAW_ARB);

        std::vector<TexVert>::iterator titer = texBuffer->begin();
        glGenBuffersARB(1, &m_VBOtex);
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_VBOtex);
        glBufferDataARB(GL_ARRAY_BUFFER_ARB, texBuffer->size()*2*sizeof(float), &(*titer), GL_STATIC_DRAW_ARB);

        std::vector<ColVert>::iterator citer = colBuffer->begin();
        glGenBuffersARB(1, &m_VBOcol);
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_VBOcol);
        glBufferDataARB(GL_ARRAY_BUFFER_ARB, colBuffer->size()*4*sizeof(float), &(*citer), GL_STATIC_DRAW_ARB);
    }
    if(transVertexCount > 0)
    {
        r = true;
        std::vector<Vertex>::iterator tit = transVertBuffer->begin();
        glGenBuffersARB(1, &m_transVBOverticies);
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_transVBOverticies);
        glBufferDataARB(GL_ARRAY_BUFFER_ARB, transVertBuffer->size()*3*sizeof(float), &(*tit), GL_STATIC_DRAW_ARB);

        std::vector<TexVert>::iterator ttit = transTexBuffer->begin();
        glGenBuffersARB(1, &m_transVBOtex);
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_transVBOtex);
        glBufferDataARB(GL_ARRAY_BUFFER_ARB, transTexBuffer->size()*2*sizeof(float), &(*ttit), GL_STATIC_DRAW_ARB);

        std::vector<ColVert>::iterator tcit = transColBuffer->begin();
        glGenBuffersARB(1, &m_transVBOcol);
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_transVBOcol);
        glBufferDataARB(GL_ARRAY_BUFFER_ARB, transColBuffer->size()*4*sizeof(float), &(*tcit), GL_STATIC_DRAW_ARB);
    }

    vertBuffer->clear();
    texBuffer->clear();
    colBuffer->clear();

    transVertBuffer->clear();
    transTexBuffer->clear();
    transColBuffer->clear();

    vertBuffer = 0;
    texBuffer = 0;
    colBuffer = 0;

    transVertBuffer = 0;
    transTexBuffer = 0;
    transColBuffer = 0;

    return r;
}
コード例 #18
0
ファイル: debugger.hpp プロジェクト: Taritsyn/LibSassHost
inline void debug_ast(AST_Node* node, std::string ind, Env* env)
{
  if (node == 0) return;
  if (ind == "") std::cerr << "####################################################################\n";
  if (dynamic_cast<Bubble*>(node)) {
    Bubble* bubble = dynamic_cast<Bubble*>(node);
    std::cerr << ind << "Bubble " << bubble;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << bubble->tabs();
    std::cerr << std::endl;
    debug_ast(bubble->node(), ind + " ", env);
  } else if (dynamic_cast<Trace*>(node)) {
    Trace* trace = dynamic_cast<Trace*>(node);
    std::cerr << ind << "Trace " << trace;
    std::cerr << " (" << pstate_source_position(node) << ")"
    << " [name:" << trace->name() << "]"
    << std::endl;
    debug_ast(trace->block(), ind + " ", env);
  } else if (dynamic_cast<At_Root_Block*>(node)) {
    At_Root_Block* root_block = dynamic_cast<At_Root_Block*>(node);
    std::cerr << ind << "At_Root_Block " << root_block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << root_block->tabs();
    std::cerr << std::endl;
    debug_ast(root_block->expression(), ind + ":", env);
    debug_ast(root_block->block(), ind + " ", env);
  } else if (dynamic_cast<CommaSequence_Selector*>(node)) {
    CommaSequence_Selector* selector = dynamic_cast<CommaSequence_Selector*>(node);
    std::cerr << ind << "CommaSequence_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " [@media:" << selector->media_block() << "]";
    std::cerr << (selector->is_invisible() ? " [INVISIBLE]": " -");
    std::cerr << (selector->has_placeholder() ? " [PLACEHOLDER]": " -");
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << std::endl;

    for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); }

//  } else if (dynamic_cast<Expression*>(node)) {
//    Expression* expression = dynamic_cast<Expression*>(node);
//    std::cerr << ind << "Expression " << expression << " " << expression->concrete_type() << std::endl;

  } else if (dynamic_cast<Parent_Selector*>(node)) {
    Parent_Selector* selector = dynamic_cast<Parent_Selector*>(node);
    std::cerr << ind << "Parent_Selector " << selector;
//    if (selector->not_selector()) cerr << " [in_declaration]";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " [" << (selector->is_real_parent_ref() ? "REAL" : "FAKE") << "]";
    std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl;
//    debug_ast(selector->selector(), ind + "->", env);

  } else if (dynamic_cast<Sequence_Selector*>(node)) {
    Sequence_Selector* selector = dynamic_cast<Sequence_Selector*>(node);
    std::cerr << ind << "Sequence_Selector " << selector
      << " (" << pstate_source_position(node) << ")"
      << " <" << selector->hash() << ">"
      << " [length:" << longToHex(selector->length()) << "]"
      << " [weight:" << longToHex(selector->specificity()) << "]"
      << " [@media:" << selector->media_block() << "]"
      << (selector->is_invisible() ? " [INVISIBLE]": " -")
      << (selector->has_placeholder() ? " [PLACEHOLDER]": " -")
      << (selector->is_optional() ? " [is_optional]": " -")
      << (selector->has_parent_ref() ? " [has parent]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
      << (selector->has_line_break() ? " [line-break]": " -")
      << " -- ";
      std::string del;
      switch (selector->combinator()) {
        case Sequence_Selector::PARENT_OF:   del = ">"; break;
        case Sequence_Selector::PRECEDES:    del = "~"; break;
        case Sequence_Selector::ADJACENT_TO: del = "+"; break;
        case Sequence_Selector::ANCESTOR_OF: del = " "; break;
        case Sequence_Selector::REFERENCE:   del = "//"; break;
      }
      // if (del = "/") del += selector->reference()->perform(&to_string) + "/";
    std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl;
    debug_ast(selector->head(), ind + " " /* + "[" + del + "]" */, env);
    if (selector->tail()) {
      debug_ast(selector->tail(), ind + "{" + del + "}", env);
    } else if(del != " ") {
      std::cerr << ind << " |" << del << "| {trailing op}" << std::endl;
    }
    SourcesSet set = selector->sources();
    // debug_sources_set(set, ind + "  @--> ");
  } else if (dynamic_cast<SimpleSequence_Selector*>(node)) {
    SimpleSequence_Selector* selector = dynamic_cast<SimpleSequence_Selector*>(node);
    std::cerr << ind << "SimpleSequence_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " [weight:" << longToHex(selector->specificity()) << "]";
    std::cerr << " [@media:" << selector->media_block() << "]";
    std::cerr << (selector->extended() ? " [extended]": " -");
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl;
    for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Wrapped_Selector*>(node)) {
    Wrapped_Selector* selector = dynamic_cast<Wrapped_Selector*>(node);
    std::cerr << ind << "Wrapped_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <<" << selector->ns_name() << ">>";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << std::endl;
    debug_ast(selector->selector(), ind + " () ", env);
  } else if (dynamic_cast<Pseudo_Selector*>(node)) {
    Pseudo_Selector* selector = dynamic_cast<Pseudo_Selector*>(node);
    std::cerr << ind << "Pseudo_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <<" << selector->ns_name() << ">>";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << std::endl;
    debug_ast(selector->expression(), ind + " <= ", env);
  } else if (dynamic_cast<Attribute_Selector*>(node)) {
    Attribute_Selector* selector = dynamic_cast<Attribute_Selector*>(node);
    std::cerr << ind << "Attribute_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <<" << selector->ns_name() << ">>";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << std::endl;
    debug_ast(selector->value(), ind + "[" + selector->matcher() + "] ", env);
  } else if (dynamic_cast<Class_Selector*>(node)) {
    Class_Selector* selector = dynamic_cast<Class_Selector*>(node);
    std::cerr << ind << "Class_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <<" << selector->ns_name() << ">>";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << std::endl;
  } else if (dynamic_cast<Id_Selector*>(node)) {
    Id_Selector* selector = dynamic_cast<Id_Selector*>(node);
    std::cerr << ind << "Id_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <<" << selector->ns_name() << ">>";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << std::endl;
  } else if (dynamic_cast<Element_Selector*>(node)) {
    Element_Selector* selector = dynamic_cast<Element_Selector*>(node);
    std::cerr << ind << "Element_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <<" << selector->ns_name() << ">>";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">";
    std::cerr << std::endl;
  } else if (dynamic_cast<Placeholder_Selector*>(node)) {

    Placeholder_Selector* selector = dynamic_cast<Placeholder_Selector*>(node);
    std::cerr << ind << "Placeholder_Selector [" << selector->ns_name() << "] " << selector
      << " <" << selector->hash() << ">"
      << " [@media:" << selector->media_block() << "]"
      << (selector->is_optional() ? " [is_optional]": " -")
      << (selector->has_line_break() ? " [line-break]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
    << std::endl;

  } else if (dynamic_cast<Simple_Selector*>(node)) {
    Simple_Selector* selector = dynamic_cast<Simple_Selector*>(node);
    std::cerr << ind << "Simple_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << std::endl;

  } else if (dynamic_cast<Selector_Schema*>(node)) {
    Selector_Schema* selector = dynamic_cast<Selector_Schema*>(node);
    std::cerr << ind << "Selector_Schema " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")"
      << (selector->at_root() && selector->at_root() ? " [@ROOT]" : "")
      << " [@media:" << selector->media_block() << "]"
      << (selector->has_line_break() ? " [line-break]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
    << std::endl;

    debug_ast(selector->contents(), ind + " ");
    // for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); }

  } else if (dynamic_cast<Selector*>(node)) {
    Selector* selector = dynamic_cast<Selector*>(node);
    std::cerr << ind << "Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << (selector->has_line_break() ? " [line-break]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
    << std::endl;

  } else if (dynamic_cast<Media_Query_Expression*>(node)) {
    Media_Query_Expression* block = dynamic_cast<Media_Query_Expression*>(node);
    std::cerr << ind << "Media_Query_Expression " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << (block->is_interpolated() ? " [is_interpolated]": " -")
    << std::endl;
    debug_ast(block->feature(), ind + " feature) ");
    debug_ast(block->value(), ind + " value) ");

  } else if (dynamic_cast<Media_Query*>(node)) {
    Media_Query* block = dynamic_cast<Media_Query*>(node);
    std::cerr << ind << "Media_Query " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << (block->is_negated() ? " [is_negated]": " -")
      << (block->is_restricted() ? " [is_restricted]": " -")
    << std::endl;
    debug_ast(block->media_type(), ind + " ");
    for(auto i : block->elements()) { debug_ast(i, ind + " ", env); }

  } else if (dynamic_cast<Media_Block*>(node)) {
    Media_Block* block = dynamic_cast<Media_Block*>(node);
    std::cerr << ind << "Media_Block " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->media_queries(), ind + " =@ ");
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Supports_Block*>(node)) {
    Supports_Block* block = dynamic_cast<Supports_Block*>(node);
    std::cerr << ind << "Supports_Block " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->condition(), ind + " =@ ");
    debug_ast(block->block(), ind + " <>");
  } else if (dynamic_cast<Supports_Operator*>(node)) {
    Supports_Operator* block = dynamic_cast<Supports_Operator*>(node);
    std::cerr << ind << "Supports_Operator " << block;
    std::cerr << " (" << pstate_source_position(node) << ")"
    << std::endl;
    debug_ast(block->left(), ind + " left) ");
    debug_ast(block->right(), ind + " right) ");
  } else if (dynamic_cast<Supports_Negation*>(node)) {
    Supports_Negation* block = dynamic_cast<Supports_Negation*>(node);
    std::cerr << ind << "Supports_Negation " << block;
    std::cerr << " (" << pstate_source_position(node) << ")"
    << std::endl;
    debug_ast(block->condition(), ind + " condition) ");
  } else if (dynamic_cast<At_Root_Query*>(node)) {
    At_Root_Query* block = dynamic_cast<At_Root_Query*>(node);
    std::cerr << ind << "At_Root_Query " << block;
    std::cerr << " (" << pstate_source_position(node) << ")"
    << std::endl;
    debug_ast(block->feature(), ind + " feature) ");
    debug_ast(block->value(), ind + " value) ");
  } else if (dynamic_cast<Supports_Declaration*>(node)) {
    Supports_Declaration* block = dynamic_cast<Supports_Declaration*>(node);
    std::cerr << ind << "Supports_Declaration " << block;
    std::cerr << " (" << pstate_source_position(node) << ")"
    << std::endl;
    debug_ast(block->feature(), ind + " feature) ");
    debug_ast(block->value(), ind + " value) ");
  } else if (dynamic_cast<Block*>(node)) {
    Block* root_block = dynamic_cast<Block*>(node);
    std::cerr << ind << "Block " << root_block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    if (root_block->is_root()) std::cerr << " [root]";
    std::cerr << " " << root_block->tabs() << std::endl;
    if (root_block->block()) for(auto i : root_block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Warning*>(node)) {
    Warning* block = dynamic_cast<Warning*>(node);
    std::cerr << ind << "Warning " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->message(), ind + " : ");
  } else if (dynamic_cast<Error*>(node)) {
    Error* block = dynamic_cast<Error*>(node);
    std::cerr << ind << "Error " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
  } else if (dynamic_cast<Debug*>(node)) {
    Debug* block = dynamic_cast<Debug*>(node);
    std::cerr << ind << "Debug " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->value(), ind + " ");
  } else if (dynamic_cast<Comment*>(node)) {
    Comment* block = dynamic_cast<Comment*>(node);
    std::cerr << ind << "Comment " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() <<
      " <" << prettyprint(block->pstate().token.ws_before()) << ">" << std::endl;
    debug_ast(block->text(), ind + "// ", env);
  } else if (dynamic_cast<If*>(node)) {
    If* block = dynamic_cast<If*>(node);
    std::cerr << ind << "If " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->predicate(), ind + " = ");
    debug_ast(block->block(), ind + " <>");
    debug_ast(block->alternative(), ind + " ><");
  } else if (dynamic_cast<Return*>(node)) {
    Return* block = dynamic_cast<Return*>(node);
    std::cerr << ind << "Return " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
  } else if (dynamic_cast<Extension*>(node)) {
    Extension* block = dynamic_cast<Extension*>(node);
    std::cerr << ind << "Extension " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->selector(), ind + "-> ", env);
  } else if (dynamic_cast<Content*>(node)) {
    Content* block = dynamic_cast<Content*>(node);
    std::cerr << ind << "Content " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [@media:" << block->media_block() << "]";
    std::cerr << " " << block->tabs() << std::endl;
  } else if (dynamic_cast<Import_Stub*>(node)) {
    Import_Stub* block = dynamic_cast<Import_Stub*>(node);
    std::cerr << ind << "Import_Stub " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << block->imp_path() << "] ";
    std::cerr << " " << block->tabs() << std::endl;
  } else if (dynamic_cast<Import*>(node)) {
    Import* block = dynamic_cast<Import*>(node);
    std::cerr << ind << "Import " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    // std::vector<std::string>         files_;
    for (auto imp : block->urls()) debug_ast(imp, ind + "@: ", env);
    debug_ast(block->media_queries(), ind + "@@ ");
  } else if (dynamic_cast<Assignment*>(node)) {
    Assignment* block = dynamic_cast<Assignment*>(node);
    std::cerr << ind << "Assignment " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <<" << block->variable() << ">> " << block->tabs() << std::endl;
    debug_ast(block->value(), ind + "=", env);
  } else if (dynamic_cast<Declaration*>(node)) {
    Declaration* block = dynamic_cast<Declaration*>(node);
    std::cerr << ind << "Declaration " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->property(), ind + " prop: ", env);
    debug_ast(block->value(), ind + " value: ", env);
    debug_ast(block->block(), ind + " ", env);
  } else if (dynamic_cast<Keyframe_Rule*>(node)) {
    Keyframe_Rule* has_block = dynamic_cast<Keyframe_Rule*>(node);
    std::cerr << ind << "Keyframe_Rule " << has_block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << has_block->tabs() << std::endl;
    if (has_block->selector()) debug_ast(has_block->selector(), ind + "@");
    if (has_block->block()) for(auto i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Directive*>(node)) {
    Directive* block = dynamic_cast<Directive*>(node);
    std::cerr << ind << "Directive " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << block->keyword() << "] " << block->tabs() << std::endl;
    debug_ast(block->selector(), ind + "~", env);
    debug_ast(block->value(), ind + "+", env);
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Each*>(node)) {
    Each* block = dynamic_cast<Each*>(node);
    std::cerr << ind << "Each " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<For*>(node)) {
    For* block = dynamic_cast<For*>(node);
    std::cerr << ind << "For " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<While*>(node)) {
    While* block = dynamic_cast<While*>(node);
    std::cerr << ind << "While " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Definition*>(node)) {
    Definition* block = dynamic_cast<Definition*>(node);
    std::cerr << ind << "Definition " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [name: " << block->name() << "] ";
    std::cerr << " [type: " << (block->type() == Sass::Definition::Type::MIXIN ? "Mixin " : "Function ") << "] ";
    // this seems to lead to segfaults some times?
    // std::cerr << " [signature: " << block->signature() << "] ";
    std::cerr << " [native: " << block->native_function() << "] ";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->parameters(), ind + " params: ", env);
    if (block->block()) debug_ast(block->block(), ind + " ", env);
  } else if (dynamic_cast<Mixin_Call*>(node)) {
    Mixin_Call* block = dynamic_cast<Mixin_Call*>(node);
    std::cerr << ind << "Mixin_Call " << block << " " << block->tabs();
    std::cerr << " [" <<  block->name() << "]";
    std::cerr << " [has_content: " << block->has_content() << "] " << std::endl;
    debug_ast(block->arguments(), ind + " args: ");
    if (block->block()) debug_ast(block->block(), ind + " ", env);
  } else if (Ruleset* ruleset = dynamic_cast<Ruleset*>(node)) {
    std::cerr << ind << "Ruleset " << ruleset;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [indent: " << ruleset->tabs() << "]";
    std::cerr << (ruleset->is_invisible() ? " [INVISIBLE]" : "");
    std::cerr << (ruleset->at_root() ? " [@ROOT]" : "");
    std::cerr << (ruleset->is_root() ? " [root]" : "");
    std::cerr << std::endl;
    debug_ast(ruleset->selector(), ind + ">");
    debug_ast(ruleset->block(), ind + " ");
  } else if (dynamic_cast<Block*>(node)) {
    Block* block = dynamic_cast<Block*>(node);
    std::cerr << ind << "Block " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << (block->is_invisible() ? " [INVISIBLE]" : "");
    std::cerr << " [indent: " << block->tabs() << "]" << std::endl;
    for(auto i : block->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Textual*>(node)) {
    Textual* expression = dynamic_cast<Textual*>(node);
    std::cerr << ind << "Textual ";
    if (expression->type() == Textual::NUMBER) std::cerr << " [NUMBER]";
    else if (expression->type() == Textual::PERCENTAGE) std::cerr << " [PERCENTAGE]";
    else if (expression->type() == Textual::DIMENSION) std::cerr << " [DIMENSION]";
    else if (expression->type() == Textual::HEX) std::cerr << " [HEX]";
    std::cerr << expression << " [" << expression->value() << "]";
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    if (expression->is_delayed()) std::cerr << " [delayed]";
    std::cerr << std::endl;
  } else if (dynamic_cast<Variable*>(node)) {
    Variable* expression = dynamic_cast<Variable*>(node);
    std::cerr << ind << "Variable " << expression;
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << expression->name() << "]" << std::endl;
    std::string name(expression->name());
    if (env && env->has(name)) debug_ast(static_cast<Expression*>((*env)[name]), ind + " -> ", env);
  } else if (dynamic_cast<Function_Call_Schema*>(node)) {
    Function_Call_Schema* expression = dynamic_cast<Function_Call_Schema*>(node);
    std::cerr << ind << "Function_Call_Schema " << expression;
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << "" << std::endl;
    debug_ast(expression->name(), ind + "name: ", env);
    debug_ast(expression->arguments(), ind + " args: ", env);
  } else if (dynamic_cast<Function_Call*>(node)) {
    Function_Call* expression = dynamic_cast<Function_Call*>(node);
    std::cerr << ind << "Function_Call " << expression;
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << expression->name() << "]";
    if (expression->is_delayed()) std::cerr << " [delayed]";
    if (expression->is_interpolant()) std::cerr << " [interpolant]";
    std::cerr << std::endl;
    debug_ast(expression->arguments(), ind + " args: ", env);
  } else if (dynamic_cast<Arguments*>(node)) {
    Arguments* expression = dynamic_cast<Arguments*>(node);
    std::cerr << ind << "Arguments " << expression;
    if (expression->is_delayed()) std::cerr << " [delayed]";
    std::cerr << " (" << pstate_source_position(node) << ")";
    if (expression->has_named_arguments()) std::cerr << " [has_named_arguments]";
    if (expression->has_rest_argument()) std::cerr << " [has_rest_argument]";
    if (expression->has_keyword_argument()) std::cerr << " [has_keyword_argument]";
    std::cerr << std::endl;
    for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Argument*>(node)) {
    Argument* expression = dynamic_cast<Argument*>(node);
    std::cerr << ind << "Argument " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << expression->value() << "]";
    std::cerr << " [name: " << expression->name() << "] ";
    std::cerr << " [rest: " << expression->is_rest_argument() << "] ";
    std::cerr << " [keyword: " << expression->is_keyword_argument() << "] " << std::endl;
    debug_ast(expression->value(), ind + " value: ", env);
  } else if (dynamic_cast<Parameters*>(node)) {
    Parameters* expression = dynamic_cast<Parameters*>(node);
    std::cerr << ind << "Parameters " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [has_optional: " << expression->has_optional_parameters() << "] ";
    std::cerr << " [has_rest: " << expression->has_rest_parameter() << "] ";
    std::cerr << std::endl;
    for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Parameter*>(node)) {
    Parameter* expression = dynamic_cast<Parameter*>(node);
    std::cerr << ind << "Parameter " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [name: " << expression->name() << "] ";
    std::cerr << " [default: " << expression->default_value() << "] ";
    std::cerr << " [rest: " << expression->is_rest_parameter() << "] " << std::endl;
  } else if (dynamic_cast<Unary_Expression*>(node)) {
    Unary_Expression* expression = dynamic_cast<Unary_Expression*>(node);
    std::cerr << ind << "Unary_Expression " << expression;
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " [delayed: " << expression->is_delayed() << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << expression->type() << "]" << std::endl;
    debug_ast(expression->operand(), ind + " operand: ", env);
  } else if (dynamic_cast<Binary_Expression*>(node)) {
    Binary_Expression* expression = dynamic_cast<Binary_Expression*>(node);
    std::cerr << ind << "Binary_Expression " << expression;
    if (expression->is_interpolant()) std::cerr << " [is interpolant] ";
    if (expression->is_left_interpolant()) std::cerr << " [left interpolant] ";
    if (expression->is_right_interpolant()) std::cerr << " [right interpolant] ";
    std::cerr << " [delayed: " << expression->is_delayed() << "] ";
    std::cerr << " [ws_before: " << expression->op().ws_before << "] ";
    std::cerr << " [ws_after: " << expression->op().ws_after << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << expression->type_name() << "]" << std::endl;
    debug_ast(expression->left(), ind + " left:  ", env);
    debug_ast(expression->right(), ind + " right: ", env);
  } else if (dynamic_cast<Map*>(node)) {
    Map* expression = dynamic_cast<Map*>(node);
    std::cerr << ind << "Map " << expression;
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [Hashed]" << std::endl;
    for (auto i : expression->elements()) {
      debug_ast(i.first, ind + " key: ");
      debug_ast(i.second, ind + " val: ");
    }
  } else if (dynamic_cast<List*>(node)) {
    List* expression = dynamic_cast<List*>(node);
    std::cerr << ind << "List " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " (" << expression->length() << ") " <<
      (expression->separator() == SASS_COMMA ? "Comma " : expression->separator() == SASS_HASH ? "Map" : "Space ") <<
      " [delayed: " << expression->is_delayed() << "] " <<
      " [interpolant: " << expression->is_interpolant() << "] " <<
      " [listized: " << expression->from_selector() << "] " <<
      " [arglist: " << expression->is_arglist() << "] " <<
      " [hash: " << expression->hash() << "] " <<
      std::endl;
    for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Content*>(node)) {
    Content* expression = dynamic_cast<Content*>(node);
    std::cerr << ind << "Content " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [@media:" << expression->media_block() << "]";
    std::cerr << " [Statement]" << std::endl;
  } else if (dynamic_cast<Boolean*>(node)) {
    Boolean* expression = dynamic_cast<Boolean*>(node);
    std::cerr << ind << "Boolean " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " [" << expression->value() << "]" << std::endl;
  } else if (dynamic_cast<Color*>(node)) {
    Color* expression = dynamic_cast<Color*>(node);
    std::cerr << ind << "Color " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [delayed: " << expression->is_delayed() << "] ";
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " [" << expression->r() << ":"  << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << std::endl;
  } else if (dynamic_cast<Number*>(node)) {
    Number* expression = dynamic_cast<Number*>(node);
    std::cerr << ind << "Number " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " [" << expression->value() << expression->unit() << "]" <<
      " [hash: " << expression->hash() << "] " <<
      std::endl;
  } else if (dynamic_cast<String_Quoted*>(node)) {
    String_Quoted* expression = dynamic_cast<String_Quoted*>(node);
    std::cerr << ind << "String_Quoted " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << prettyprint(expression->value()) << "]";
    if (expression->is_delayed()) std::cerr << " [delayed]";
    if (expression->is_interpolant()) std::cerr << " [interpolant]";
    if (expression->quote_mark()) std::cerr << " [quote_mark: " << expression->quote_mark() << "]";
    std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
  } else if (dynamic_cast<String_Constant*>(node)) {
    String_Constant* expression = dynamic_cast<String_Constant*>(node);
    std::cerr << ind << "String_Constant " << expression;
    if (expression->concrete_type()) {
      std::cerr << " " << expression->concrete_type();
    }
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << prettyprint(expression->value()) << "]";
    if (expression->is_delayed()) std::cerr << " [delayed]";
    if (expression->is_interpolant()) std::cerr << " [interpolant]";
    std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
  } else if (dynamic_cast<String_Schema*>(node)) {
    String_Schema* expression = dynamic_cast<String_Schema*>(node);
    std::cerr << ind << "String_Schema " << expression;
    std::cerr << " " << expression->concrete_type();
    if (expression->is_delayed()) std::cerr << " [delayed]";
    if (expression->is_interpolant()) std::cerr << " [is interpolant]";
    if (expression->has_interpolant()) std::cerr << " [has interpolant]";
    if (expression->is_left_interpolant()) std::cerr << " [left interpolant] ";
    if (expression->is_right_interpolant()) std::cerr << " [right interpolant] ";
    std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
    for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<String*>(node)) {
    String* expression = dynamic_cast<String*>(node);
    std::cerr << ind << "String " << expression;
    std::cerr << " " << expression->concrete_type();
    std::cerr << " (" << pstate_source_position(node) << ")";
    if (expression->is_interpolant()) std::cerr << " [interpolant]";
    std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
  } else if (dynamic_cast<Expression*>(node)) {
    Expression* expression = dynamic_cast<Expression*>(node);
    std::cerr << ind << "Expression " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    switch (expression->concrete_type()) {
      case Expression::Concrete_Type::NONE: std::cerr << " [NONE]"; break;
      case Expression::Concrete_Type::BOOLEAN: std::cerr << " [BOOLEAN]"; break;
      case Expression::Concrete_Type::NUMBER: std::cerr << " [NUMBER]"; break;
      case Expression::Concrete_Type::COLOR: std::cerr << " [COLOR]"; break;
      case Expression::Concrete_Type::STRING: std::cerr << " [STRING]"; break;
      case Expression::Concrete_Type::LIST: std::cerr << " [LIST]"; break;
      case Expression::Concrete_Type::MAP: std::cerr << " [MAP]"; break;
      case Expression::Concrete_Type::SELECTOR: std::cerr << " [SELECTOR]"; break;
      case Expression::Concrete_Type::NULL_VAL: std::cerr << " [NULL_VAL]"; break;
      case Expression::Concrete_Type::C_WARNING: std::cerr << " [C_WARNING]"; break;
      case Expression::Concrete_Type::C_ERROR: std::cerr << " [C_ERROR]"; break;
      case Expression::Concrete_Type::NUM_TYPES: std::cerr << " [NUM_TYPES]"; break;
    }
    std::cerr << std::endl;
  } else if (dynamic_cast<Has_Block*>(node)) {
    Has_Block* has_block = dynamic_cast<Has_Block*>(node);
    std::cerr << ind << "Has_Block " << has_block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << has_block->tabs() << std::endl;
    if (has_block->block()) for(auto i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Statement*>(node)) {
    Statement* statement = dynamic_cast<Statement*>(node);
    std::cerr << ind << "Statement " << statement;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << statement->tabs() << std::endl;
  }

  if (ind == "") std::cerr << "####################################################################\n";
}
コード例 #19
0
ファイル: PlayState.cpp プロジェクト: briangwald/Tetris-Clone
void PlayState::HandleInput()
{
	static bool down_is_pressed = false;
	static bool left_is_pressed = false;
	static bool right_is_pressed = false;


	if (SDL_PollEvent(&event))
	{
		if (event.type == SDL_QUIT)
		{
			while (!TheGame::Instance()->GetGameStates()->empty())
			{
				TheGame::Instance()->GetGameStates()->pop();
			}
			return;
		}
		if (event.type == SDL_KEYDOWN)
		{
			
			if (event.key.keysym.sym == SDLK_ESCAPE)
			{
				TheGame::Instance()->GetGameStates()->pop();

				return;
			}

			Block* nextBlock = TheGame::Instance()->GetNextBlock();

			if (event.key.keysym.sym == SDLK_SPACE)
			{
				if (!nextBlock->CheckEntityCollision(LEFT) && !nextBlock->CheckEntityCollision(RIGHT) && !nextBlock->CheckEntityCollision(DOWN))
				{
					TheGame::Instance()->SwapBlock();
				}
			}

			Block* focusBlock = TheGame::Instance()->GetFocusBlock();

			if (event.key.keysym.sym == SDLK_UP)
			{
				if (!focusBlock->CheckRotationCollision())
				{
					focusBlock->Rotate();
				}
			}
			// TODO: Consolidate Wall and Entity Collision into a signle function for readability.

			if (event.key.keysym.sym == SDLK_LEFT)
			{
				left_is_pressed = true;
				if (!focusBlock->CheckWallCollision(LEFT) && !focusBlock->CheckEntityCollision(LEFT))
				{
					focusBlock->Move(LEFT);
				}
			}
			if (event.key.keysym.sym == SDLK_RIGHT)
			{
				right_is_pressed = true;
				if (!focusBlock->CheckWallCollision(RIGHT) && !focusBlock->CheckEntityCollision(RIGHT))
				{
					focusBlock->Move(RIGHT);
				}
			}
			if (event.key.keysym.sym == SDLK_DOWN)
			{
				down_is_pressed = true;
				if (!focusBlock->CheckWallCollision(DOWN) && !focusBlock->CheckEntityCollision(DOWN))
				{
					focusBlock->Move(DOWN);
				}
			}
		}
	}
}
コード例 #20
0
ファイル: Join.cpp プロジェクト: bamx23/ClickHouse
bool Join::insertFromBlock(const Block & block)
{
    std::unique_lock lock(rwlock);

    if (empty())
        throw Exception("Logical error: Join was not initialized", ErrorCodes::LOGICAL_ERROR);

    size_t keys_size = key_names_right.size();
    ColumnRawPtrs key_columns(keys_size);

    /// Rare case, when keys are constant. To avoid code bloat, simply materialize them.
    Columns materialized_columns;

    /// Memoize key columns to work.
    for (size_t i = 0; i < keys_size; ++i)
    {
        key_columns[i] = block.getByName(key_names_right[i]).column.get();

        if (ColumnPtr converted = key_columns[i]->convertToFullColumnIfConst())
        {
            materialized_columns.emplace_back(converted);
            key_columns[i] = materialized_columns.back().get();
        }
    }

    /// We will insert to the map only keys, where all components are not NULL.
    ColumnPtr null_map_holder;
    ConstNullMapPtr null_map{};
    extractNestedColumnsAndNullMap(key_columns, null_map_holder, null_map);

    size_t rows = block.rows();

    blocks.push_back(block);
    Block * stored_block = &blocks.back();

    if (getFullness(kind))
    {
        /** Transfer the key columns to the beginning of the block.
          * This is where NonJoinedBlockInputStream will wait for them.
          */
        size_t key_num = 0;
        for (const auto & name : key_names_right)
        {
            size_t pos = stored_block->getPositionByName(name);
            ColumnWithTypeAndName col = stored_block->safeGetByPosition(pos);
            stored_block->erase(pos);
            stored_block->insert(key_num, std::move(col));
            ++key_num;
        }
    }
    else
    {
        /// Remove the key columns from stored_block, as they are not needed.
        for (const auto & name : key_names_right)
            stored_block->erase(stored_block->getPositionByName(name));
    }

    size_t size = stored_block->columns();

    /// Rare case, when joined columns are constant. To avoid code bloat, simply materialize them.
    for (size_t i = 0; i < size; ++i)
    {
        ColumnPtr col = stored_block->safeGetByPosition(i).column;
        if (ColumnPtr converted = col->convertToFullColumnIfConst())
            stored_block->safeGetByPosition(i).column = converted;
    }

    /// In case of LEFT and FULL joins, if use_nulls, convert joined columns to Nullable.
    if (use_nulls && (kind == ASTTableJoin::Kind::Left || kind == ASTTableJoin::Kind::Full))
    {
        for (size_t i = getFullness(kind) ? keys_size : 0; i < size; ++i)
        {
            convertColumnToNullable(stored_block->getByPosition(i));
        }
    }

    if (kind != ASTTableJoin::Kind::Cross)
    {
        /// Fill the hash table.
        if (!getFullness(kind))
        {
            if (strictness == ASTTableJoin::Strictness::Any)
                insertFromBlockImpl<ASTTableJoin::Strictness::Any>(type, maps_any, rows, key_columns, keys_size, key_sizes, stored_block, null_map, pool);
            else
                insertFromBlockImpl<ASTTableJoin::Strictness::All>(type, maps_all, rows, key_columns, keys_size, key_sizes, stored_block, null_map, pool);
        }
        else
        {
            if (strictness == ASTTableJoin::Strictness::Any)
                insertFromBlockImpl<ASTTableJoin::Strictness::Any>(type, maps_any_full, rows, key_columns, keys_size, key_sizes, stored_block, null_map, pool);
            else
                insertFromBlockImpl<ASTTableJoin::Strictness::All>(type, maps_all_full, rows, key_columns, keys_size, key_sizes, stored_block, null_map, pool);
        }
    }

    if (!checkSizeLimits())
    {
        switch (overflow_mode)
        {
            case OverflowMode::THROW:
                throw Exception("Join size limit exceeded."
                    " Rows: " + toString(getTotalRowCount()) +
                    ", limit: " + toString(max_rows) +
                    ". Bytes: " + toString(getTotalByteCount()) +
                    ", limit: " + toString(max_bytes) + ".",
                    ErrorCodes::SET_SIZE_LIMIT_EXCEEDED);

            case OverflowMode::BREAK:
                return false;

            default:
                throw Exception("Logical error: unknown overflow mode", ErrorCodes::LOGICAL_ERROR);
        }
    }

    return true;
}
コード例 #21
0
ファイル: point.C プロジェクト: pamoakoy/daisy-model
ZXPoint::ZXPoint (const Block& al)
  : z (al.number ("z")),
    x (al.number ("x"))
{ }
コード例 #22
0
ファイル: Join.cpp プロジェクト: bamx23/ClickHouse
void Join::joinBlockImpl(Block & block, const Maps & maps) const
{
    size_t keys_size = key_names_left.size();
    ColumnRawPtrs key_columns(keys_size);

    /// Rare case, when keys are constant. To avoid code bloat, simply materialize them.
    Columns materialized_columns;

    /// Memoize key columns to work with.
    for (size_t i = 0; i < keys_size; ++i)
    {
        key_columns[i] = block.getByName(key_names_left[i]).column.get();

        if (ColumnPtr converted = key_columns[i]->convertToFullColumnIfConst())
        {
            materialized_columns.emplace_back(converted);
            key_columns[i] = materialized_columns.back().get();
        }
    }

    /// Keys with NULL value in any column won't join to anything.
    ColumnPtr null_map_holder;
    ConstNullMapPtr null_map{};
    extractNestedColumnsAndNullMap(key_columns, null_map_holder, null_map);

    size_t existing_columns = block.columns();

    /** If you use FULL or RIGHT JOIN, then the columns from the "left" table must be materialized.
      * Because if they are constants, then in the "not joined" rows, they may have different values
      *  - default values, which can differ from the values of these constants.
      */
    if (getFullness(kind))
    {
        for (size_t i = 0; i < existing_columns; ++i)
        {
            auto & col = block.getByPosition(i).column;

            if (ColumnPtr converted = col->convertToFullColumnIfConst())
                col = converted;

            /// If use_nulls, convert left columns (except keys) to Nullable.
            if (use_nulls)
            {
                if (std::end(key_names_left) == std::find(key_names_left.begin(), key_names_left.end(), block.getByPosition(i).name))
                    convertColumnToNullable(block.getByPosition(i));
            }
        }
    }

    /** For LEFT/INNER JOIN, the saved blocks do not contain keys.
      * For FULL/RIGHT JOIN, the saved blocks contain keys;
      *  but they will not be used at this stage of joining (and will be in `AdderNonJoined`), and they need to be skipped.
      */
    size_t num_columns_to_skip = 0;
    if (getFullness(kind))
        num_columns_to_skip = keys_size;

    /// Add new columns to the block.
    size_t num_columns_to_add = sample_block_with_columns_to_add.columns();
    MutableColumns added_columns;
    added_columns.reserve(num_columns_to_add);

    std::vector<size_t> right_indexes;
    right_indexes.reserve(num_columns_to_add);

    for (size_t i = 0; i < num_columns_to_add; ++i)
    {
        const ColumnWithTypeAndName & src_column = sample_block_with_columns_to_add.safeGetByPosition(i);

        /// Don't insert column if it's in left block.
        if (!block.has(src_column.name))
        {
            added_columns.push_back(src_column.column->cloneEmpty());
            added_columns.back()->reserve(src_column.column->size());
            right_indexes.push_back(num_columns_to_skip + i);
        }
    }

    size_t rows = block.rows();

    /// Used with ANY INNER JOIN
    std::unique_ptr<IColumn::Filter> filter;

    if ((kind == ASTTableJoin::Kind::Inner || kind == ASTTableJoin::Kind::Right) && strictness == ASTTableJoin::Strictness::Any)
        filter = std::make_unique<IColumn::Filter>(rows);

    /// Used with ALL ... JOIN
    IColumn::Offset current_offset = 0;
    std::unique_ptr<IColumn::Offsets> offsets_to_replicate;

    if (strictness == ASTTableJoin::Strictness::All)
        offsets_to_replicate = std::make_unique<IColumn::Offsets>(rows);

    switch (type)
    {
    #define M(TYPE) \
        case Join::Type::TYPE: \
            joinBlockImplType<KIND, STRICTNESS, typename KeyGetterForType<Join::Type::TYPE>::Type>(\
                *maps.TYPE, rows, key_columns, key_sizes, added_columns, null_map, \
                filter, current_offset, offsets_to_replicate, right_indexes); \
            break;
        APPLY_FOR_JOIN_VARIANTS(M)
    #undef M

        default:
            throw Exception("Unknown JOIN keys variant.", ErrorCodes::UNKNOWN_SET_DATA_VARIANT);
    }

    for (size_t i = 0; i < num_columns_to_add; ++i)
    {
        const ColumnWithTypeAndName & sample_col = sample_block_with_columns_to_add.getByPosition(i);
        block.insert(ColumnWithTypeAndName(std::move(added_columns[i]), sample_col.type, sample_col.name));
    }

    /// If ANY INNER | RIGHT JOIN - filter all the columns except the new ones.
    if (filter)
        for (size_t i = 0; i < existing_columns; ++i)
            block.safeGetByPosition(i).column = block.safeGetByPosition(i).column->filter(*filter, -1);

    /// If ALL ... JOIN - we replicate all the columns except the new ones.
    if (offsets_to_replicate)
        for (size_t i = 0; i < existing_columns; ++i)
            block.safeGetByPosition(i).column = block.safeGetByPosition(i).column->replicate(*offsets_to_replicate);
}
コード例 #23
0
ファイル: lcm.cpp プロジェクト: AllenWeb/openjdk-1
//------------------------------implicit_null_check----------------------------
// Detect implicit-null-check opportunities.  Basically, find NULL checks
// with suitable memory ops nearby.  Use the memory op to do the NULL check.
// I can generate a memory op if there is not one nearby.
// The proj is the control projection for the not-null case.
// The val is the pointer being checked for nullness.
void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) {
  // Assume if null check need for 0 offset then always needed
  // Intel solaris doesn't support any null checks yet and no
  // mechanism exists (yet) to set the switches at an os_cpu level
  if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return;

  // Make sure the ptr-is-null path appears to be uncommon!
  float f = end()->as_MachIf()->_prob;
  if( proj->Opcode() == Op_IfTrue ) f = 1.0f - f;
  if( f > PROB_UNLIKELY_MAG(4) ) return;

  uint bidx = 0;                // Capture index of value into memop
  bool was_store;               // Memory op is a store op

  // Get the successor block for if the test ptr is non-null
  Block* not_null_block;  // this one goes with the proj
  Block* null_block;
  if (_nodes[_nodes.size()-1] == proj) {
    null_block     = _succs[0];
    not_null_block = _succs[1];
  } else {
    assert(_nodes[_nodes.size()-2] == proj, "proj is one or the other");
    not_null_block = _succs[0];
    null_block     = _succs[1];
  }
  while (null_block->is_Empty() == Block::empty_with_goto) {
    null_block     = null_block->_succs[0];
  }

  // Search the exception block for an uncommon trap.
  // (See Parse::do_if and Parse::do_ifnull for the reason
  // we need an uncommon trap.  Briefly, we need a way to
  // detect failure of this optimization, as in 6366351.)
  {
    bool found_trap = false;
    for (uint i1 = 0; i1 < null_block->_nodes.size(); i1++) {
      Node* nn = null_block->_nodes[i1];
      if (nn->is_MachCall() &&
          nn->as_MachCall()->entry_point() ==
          SharedRuntime::uncommon_trap_blob()->instructions_begin()) {
        const Type* trtype = nn->in(TypeFunc::Parms)->bottom_type();
        if (trtype->isa_int() && trtype->is_int()->is_con()) {
          jint tr_con = trtype->is_int()->get_con();
          Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(tr_con);
          Deoptimization::DeoptAction action = Deoptimization::trap_request_action(tr_con);
          assert((int)reason < (int)BitsPerInt, "recode bit map");
          if (is_set_nth_bit(allowed_reasons, (int) reason)
              && action != Deoptimization::Action_none) {
            // This uncommon trap is sure to recompile, eventually.
            // When that happens, C->too_many_traps will prevent
            // this transformation from happening again.
            found_trap = true;
          }
        }
        break;
      }
    }
    if (!found_trap) {
      // We did not find an uncommon trap.
      return;
    }
  }

  // Search the successor block for a load or store who's base value is also
  // the tested value.  There may be several.
  Node_List *out = new Node_List(Thread::current()->resource_area());
  MachNode *best = NULL;        // Best found so far
  for (DUIterator i = val->outs(); val->has_out(i); i++) {
    Node *m = val->out(i);
    if( !m->is_Mach() ) continue;
    MachNode *mach = m->as_Mach();
    was_store = false;
    switch( mach->ideal_Opcode() ) {
    case Op_LoadB:
    case Op_LoadUS:
    case Op_LoadD:
    case Op_LoadF:
    case Op_LoadI:
    case Op_LoadL:
    case Op_LoadP:
    case Op_LoadN:
    case Op_LoadS:
    case Op_LoadKlass:
    case Op_LoadNKlass:
    case Op_LoadRange:
    case Op_LoadD_unaligned:
    case Op_LoadL_unaligned:
      assert(mach->in(2) == val, "should be address");
      break;
    case Op_StoreB:
    case Op_StoreC:
    case Op_StoreCM:
    case Op_StoreD:
    case Op_StoreF:
    case Op_StoreI:
    case Op_StoreL:
    case Op_StoreP:
    case Op_StoreN:
      was_store = true;         // Memory op is a store op
      // Stores will have their address in slot 2 (memory in slot 1).
      // If the value being nul-checked is in another slot, it means we
      // are storing the checked value, which does NOT check the value!
      if( mach->in(2) != val ) continue;
      break;                    // Found a memory op?
    case Op_StrComp:
    case Op_StrEquals:
    case Op_StrIndexOf:
    case Op_AryEq:
      // Not a legit memory op for implicit null check regardless of
      // embedded loads
      continue;
    default:                    // Also check for embedded loads
      if( !mach->needs_anti_dependence_check() )
        continue;               // Not an memory op; skip it
      {
        // Check that value is used in memory address.
        Node* base;
        Node* index;
        const MachOper* oper = mach->memory_inputs(base, index);
        if (oper == NULL || oper == (MachOper*)-1) {
          continue;             // Not an memory op; skip it
        }
        if (val == base ||
            val == index && val->bottom_type()->isa_narrowoop()) {
          break;                // Found it
        } else {
          continue;             // Skip it
        }
      }
      break;
    }
    // check if the offset is not too high for implicit exception
    {
      intptr_t offset = 0;
      const TypePtr *adr_type = NULL;  // Do not need this return value here
      const Node* base = mach->get_base_and_disp(offset, adr_type);
      if (base == NULL || base == NodeSentinel) {
        // Narrow oop address doesn't have base, only index
        if( val->bottom_type()->isa_narrowoop() &&
            MacroAssembler::needs_explicit_null_check(offset) )
          continue;             // Give up if offset is beyond page size
        // cannot reason about it; is probably not implicit null exception
      } else {
        const TypePtr* tptr;
        if (UseCompressedOops && Universe::narrow_oop_shift() == 0) {
          // 32-bits narrow oop can be the base of address expressions
          tptr = base->bottom_type()->make_ptr();
        } else {
          // only regular oops are expected here
          tptr = base->bottom_type()->is_ptr();
        }
        // Give up if offset is not a compile-time constant
        if( offset == Type::OffsetBot || tptr->_offset == Type::OffsetBot )
          continue;
        offset += tptr->_offset; // correct if base is offseted
        if( MacroAssembler::needs_explicit_null_check(offset) )
          continue;             // Give up is reference is beyond 4K page size
      }
    }

    // Check ctrl input to see if the null-check dominates the memory op
    Block *cb = cfg->_bbs[mach->_idx];
    cb = cb->_idom;             // Always hoist at least 1 block
    if( !was_store ) {          // Stores can be hoisted only one block
      while( cb->_dom_depth > (_dom_depth + 1))
        cb = cb->_idom;         // Hoist loads as far as we want
      // The non-null-block should dominate the memory op, too. Live
      // range spilling will insert a spill in the non-null-block if it is
      // needs to spill the memory op for an implicit null check.
      if (cb->_dom_depth == (_dom_depth + 1)) {
        if (cb != not_null_block) continue;
        cb = cb->_idom;
      }
    }
    if( cb != this ) continue;

    // Found a memory user; see if it can be hoisted to check-block
    uint vidx = 0;              // Capture index of value into memop
    uint j;
    for( j = mach->req()-1; j > 0; j-- ) {
      if( mach->in(j) == val ) vidx = j;
      // Block of memory-op input
      Block *inb = cfg->_bbs[mach->in(j)->_idx];
      Block *b = this;          // Start from nul check
      while( b != inb && b->_dom_depth > inb->_dom_depth )
        b = b->_idom;           // search upwards for input
      // See if input dominates null check
      if( b != inb )
        break;
    }
    if( j > 0 )
      continue;
    Block *mb = cfg->_bbs[mach->_idx];
    // Hoisting stores requires more checks for the anti-dependence case.
    // Give up hoisting if we have to move the store past any load.
    if( was_store ) {
      Block *b = mb;            // Start searching here for a local load
      // mach use (faulting) trying to hoist
      // n might be blocker to hoisting
      while( b != this ) {
        uint k;
        for( k = 1; k < b->_nodes.size(); k++ ) {
          Node *n = b->_nodes[k];
          if( n->needs_anti_dependence_check() &&
              n->in(LoadNode::Memory) == mach->in(StoreNode::Memory) )
            break;              // Found anti-dependent load
        }
        if( k < b->_nodes.size() )
          break;                // Found anti-dependent load
        // Make sure control does not do a merge (would have to check allpaths)
        if( b->num_preds() != 2 ) break;
        b = cfg->_bbs[b->pred(1)->_idx]; // Move up to predecessor block
      }
      if( b != this ) continue;
    }

    // Make sure this memory op is not already being used for a NullCheck
    Node *e = mb->end();
    if( e->is_MachNullCheck() && e->in(1) == mach )
      continue;                 // Already being used as a NULL check

    // Found a candidate!  Pick one with least dom depth - the highest
    // in the dom tree should be closest to the null check.
    if( !best ||
        cfg->_bbs[mach->_idx]->_dom_depth < cfg->_bbs[best->_idx]->_dom_depth ) {
      best = mach;
      bidx = vidx;

    }
  }
  // No candidate!
  if( !best ) return;

  // ---- Found an implicit null check
  extern int implicit_null_checks;
  implicit_null_checks++;

  // Hoist the memory candidate up to the end of the test block.
  Block *old_block = cfg->_bbs[best->_idx];
  old_block->find_remove(best);
  add_inst(best);
  cfg->_bbs.map(best->_idx,this);

  // Move the control dependence
  if (best->in(0) && best->in(0) == old_block->_nodes[0])
    best->set_req(0, _nodes[0]);

  // Check for flag-killing projections that also need to be hoisted
  // Should be DU safe because no edge updates.
  for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) {
    Node* n = best->fast_out(j);
    if( n->Opcode() == Op_MachProj ) {
      cfg->_bbs[n->_idx]->find_remove(n);
      add_inst(n);
      cfg->_bbs.map(n->_idx,this);
    }
  }

  Compile *C = cfg->C;
  // proj==Op_True --> ne test; proj==Op_False --> eq test.
  // One of two graph shapes got matched:
  //   (IfTrue  (If (Bool NE (CmpP ptr NULL))))
  //   (IfFalse (If (Bool EQ (CmpP ptr NULL))))
  // NULL checks are always branch-if-eq.  If we see a IfTrue projection
  // then we are replacing a 'ne' test with a 'eq' NULL check test.
  // We need to flip the projections to keep the same semantics.
  if( proj->Opcode() == Op_IfTrue ) {
    // Swap order of projections in basic block to swap branch targets
    Node *tmp1 = _nodes[end_idx()+1];
    Node *tmp2 = _nodes[end_idx()+2];
    _nodes.map(end_idx()+1, tmp2);
    _nodes.map(end_idx()+2, tmp1);
    Node *tmp = new (C, 1) Node(C->top()); // Use not NULL input
    tmp1->replace_by(tmp);
    tmp2->replace_by(tmp1);
    tmp->replace_by(tmp2);
    tmp->destruct();
  }

  // Remove the existing null check; use a new implicit null check instead.
  // Since schedule-local needs precise def-use info, we need to correct
  // it as well.
  Node *old_tst = proj->in(0);
  MachNode *nul_chk = new (C) MachNullCheckNode(old_tst->in(0),best,bidx);
  _nodes.map(end_idx(),nul_chk);
  cfg->_bbs.map(nul_chk->_idx,this);
  // Redirect users of old_test to nul_chk
  for (DUIterator_Last i2min, i2 = old_tst->last_outs(i2min); i2 >= i2min; --i2)
    old_tst->last_out(i2)->set_req(0, nul_chk);
  // Clean-up any dead code
  for (uint i3 = 0; i3 < old_tst->req(); i3++)
    old_tst->set_req(i3, NULL);

  cfg->latency_from_uses(nul_chk);
  cfg->latency_from_uses(best);
}
コード例 #24
0
ファイル: image.cpp プロジェクト: aoboturov/m2-mo-cpp-project
float MeanColor::compute(const Block& lhs, const Block& rhs) const
{
        // Determine top/bottom coordinates of blocks in images.
        const img_coord_t     lhs_t = lhs.get_top(),
                        lhs_b = min(lhs.get_top()+lhs.get_height(), lhs.get_img()->get_height()),
                        rhs_t = rhs.get_top(),
                        rhs_b = min(rhs.get_top()+rhs.get_height(), rhs.get_img()->get_height());
        // Determine left/right coordinates of blocks in images.
        const img_coord_t     lhs_l = lhs.get_left(),
                        lhs_r = min(lhs.get_left()+lhs.get_width(), lhs.get_img()->get_width()),
                        rhs_l = rhs.get_left(),
                        rhs_r = min(rhs.get_left()+rhs.get_width(), rhs.get_img()->get_width());
        long samplesCounter = 0l;
	long meanColors[2][LAYER_CNT];
	memset(meanColors, 0, sizeof(long) * 2 * LAYER_CNT);
	for (img_coord_t lt = lhs_t, rt = rhs_t; lt < lhs_b && rt < rhs_b; lt++, rt++)
            for (img_coord_t ll = lhs_l, rl = rhs_l; ll < lhs_r && rl < rhs_r; ll++, rl++)
                for (int layer = FIRST; layer < LAYER_CNT; layer++) {
				meanColors[0][layer] += (*(lhs.get_img()))(ll, lt, layer);
				meanColors[1][layer] += (*(rhs.get_img()))(rl, rt, layer);
				samplesCounter++;
                        }
	float score = 0.f, tmp_score;
	// L1 Error
	for (int layer = FIRST; layer < LAYER_CNT; layer++) {
        score += (abs(meanColors[0][layer]-meanColors[1][layer])/samplesCounter/255.f);
	}
	return 1-score/(float)LAYER_CNT;
}
コード例 #25
0
ファイル: landscape.cpp プロジェクト: RafiKueng/TankGame
void Landscape::init()
{
	// init variables
	int dim = FIELD_SIZE;
	generate = new Generator(_levelNr); //init generator with fix random seed, change this later to TIME or something..

	//generating textures
	//texStreet = generate->gStreetTexture();

	//generating skybox
	_skybox = new Skybox();

	// generating map
	map = new TerrainType*[dim];
	generate->Terrain(dim, map, Blocks, Streets, Places);

	// for pop density
	//choose the center of the town, somewhere near the center of map
	int midX = rand()%(FIELD_SIZE/2)+FIELD_SIZE/4;
	int midZ = rand()%(FIELD_SIZE/2)+FIELD_SIZE/4;

	//generating houses
	Houses.clear();
	for (unsigned int i = 0; i<Blocks.size(); ++i)
	{
		Block * b = Blocks.at(i);
		int * mp = b->getMidPoint();
		int x = mp[0];
		int z = mp[1];
		int pd = 100 - sqrtf( (mp[0]-midX)*(mp[0]-midX)+(mp[1]-midZ)*(mp[1]-midZ) ) * 100 / (FIELD_SIZE);
		b->setPopDens(pd);
		generate->gBlock(b, Houses); //, mapHouse)
	}

	for (unsigned int i = 0; i<Houses.size(); ++i)
	{
		generate->gHouse(Houses.at(i));
	}

	if(DEBUG_HOUSES)
	{
		for (int i = 0; i<Houses.size(); ++i)
		{
			House * h = Houses.at(i);
			std::cout << "house nr."<<i<<": "<<h->x1() <<"/"<<h->z1()<<" ; "<<h->x2() <<"/"<<h->z2()<<std::endl;
		}
	}

	//generate powerups
	//////////////////////////

	// map for quick access to power ups
	PowerupPointerMap = new PowerUp**[dim];
	for (int i = 0; i<dim;++i)
	{
		*(PowerupPointerMap+i) = new PowerUp*[dim];
		for (int j=0; j<dim; j++)
		{
			PowerupPointerMap[i][j] = 0;
		}
	}

	//create all the power ups..
	for (unsigned int i = 0; i<N_POWERUPS; ++i)
	{
		int *loc = this->getFreeLocation();
		PowerUp * pu = new PowerUp(loc, PowerupType(rand()%2+1));
		if(DEBUG_LANDSCAPE){std::cout << "Created powerup nr."<<i<<" at "<<loc[0]<<" / "<<loc[1]<<std::endl;}
		Powerups.push_back(pu);
		PowerupPointerMap[loc[0]][loc[1]] = pu;
	}
}
コード例 #26
0
ファイル: image.cpp プロジェクト: aoboturov/m2-mo-cpp-project
float MCmse::compute(const Block& lhs, const Block& rhs) const
{
        // Determine top/bottom coordinates of blocks in images.
        const img_coord_t     lhs_t = lhs.get_top(),
                        lhs_b = min(lhs.get_top()+lhs.get_height(), lhs.get_img()->get_height()),
                        rhs_t = rhs.get_top(),
                        rhs_b = min(rhs.get_top()+rhs.get_height(), rhs.get_img()->get_height());
        // Determine left/right coordinates of blocks in images.
        const img_coord_t     lhs_l = lhs.get_left(),
                        lhs_r = min(lhs.get_left()+lhs.get_width(), lhs.get_img()->get_width()),
                        rhs_l = rhs.get_left(),
                        rhs_r = min(rhs.get_left()+rhs.get_width(), rhs.get_img()->get_width());
        long samplesCounter=0;
	float sum=0;
		for (img_coord_t lt = lhs_t, rt = rhs_t; lt < lhs_b && rt < rhs_b; lt++, rt++){
            for (img_coord_t ll = lhs_l, rl = rhs_l; ll < lhs_r && rl < rhs_r; ll++, rl++){
                for (int layer = FIRST; layer < LAYER_CNT; layer++) {
					if(rand()%4==0)
					{				
						float temp=((*(lhs.get_img()))(ll, lt, layer) - (*(rhs.get_img()))(rl, rt, layer));
						sum +=  temp * temp/65025.0;
						samplesCounter++;
                    }
				}
			}
		}
	return 1. - sum/samplesCounter;
}
コード例 #27
0
ファイル: b_plus_tree.cpp プロジェクト: AlecWong/DBSQL
void BPlusTree::_insertNewBlk(Block &blk1, const AttrType &k, Block &blk2) {
    Node n1 = Node(blk1), n2 = Node(blk2);
    int i;
    if( n1.isRoot() ) {
        Node newNode(true, false);
        Block newBlk = bufferManager->newBlock(filename);
        newNode.appendP(blk1.getPos());
        newNode.appendK(k);
        newNode.appendP(blk2.getPos());
        
        // update the former root and write it to block
        n1.setRoot(false);
        n1.write2Blk(blk1, typeId, strLen, bufferManager);
        
        n2.setRoot(false);
        
        std::cout << "_insertNewBlk == n1.isLeaf() " << (int)n1.isLeaf() << std::endl;
        std::cout << "_insertNewBlk == n2.isLeaf() " << (int)n2.isLeaf() << std::endl;
        
        n2.write2Blk(blk2, typeId, strLen, bufferManager);
        
        // update the B+ tree and write new parent to block
        setRootNode(newNode);
        setRootPos(newBlk.getPos());
        newNode.write2Blk(newBlk, typeId, strLen, bufferManager);
    }
    else {
        // retrieve the parent
        stk.pop();
        Block opBlk;
        bufferManager->getBlock(filename, stk.top(), opBlk);
        Node opNode(opBlk);
        
        for( i = 0; i < opNode.getPSize(); i++ ) {
            if( opNode.getP(i) == blk1.getPos() ) {
                opNode.insert(k, blk2.getPos(), i+1);
            }
        }
        
        if( opNode.getKSize() < fanout ) {
            opNode.write2Blk(opBlk, typeId, strLen, bufferManager);
        }
        else { // this parent node still need to split
            Node npNode1(false, true), npNode2(false, true);
            Block npBlk = bufferManager->newBlock(filename);
            
            npNode1.setRoot(opNode.isRoot());
            npNode2.setRoot(opNode.isRoot());
            
            npNode1.setLeaf(opNode.isLeaf());
            npNode2.setLeaf(opNode.isLeaf());
            
            for( i = 0; i < (fanout + 1) / 2 - 1; i++ ) {
                npNode1.appendK(opNode.getK(i));
                npNode1.appendP(opNode.getP(i));
            }
            AttrType nk = opNode.getK(i);
            npNode1.appendP(opNode.getP(i));
            for( i = (fanout + 1) / 2; i < fanout; i++ ) {
                npNode2.appendK(opNode.getK(i));
                npNode2.appendP(opNode.getP(i));
            }
            npNode2.appendP(opNode.getP(i));
            
            npNode1.write2Blk(opBlk, typeId, strLen, bufferManager);
            npNode2.write2Blk(npBlk, typeId, strLen, bufferManager);
            
            _insertNewBlk(opBlk, nk, npBlk);
        }
    }
}
コード例 #28
0
/*
 * Insert erase events into the event stream.
 * The strategy is to clean up all invalid pages instantly.
 */
void Block_manager::insert_events(Event &event)
{
    // Calculate if GC should be activated.
    float used = (int)invalid_list.size() + (int)log_active + (int)data_active - (int)free_list.size();
    float total = NUMBER_OF_ADDRESSABLE_BLOCKS;
    float ratio = used/total;

    if (ratio < 0.90) // Magic number
        return;

    uint num_to_erase = 5; // More Magic!

    //printf("%i %i %i\n", invalid_list.size(), log_active, data_active);

    // First step and least expensive is to go though invalid list. (Only used by FAST)
    while (num_to_erase != 0 && invalid_list.size() != 0)
    {
        Event erase_event = Event(ERASE, event.get_logical_address(), 1, event.get_start_time());
        erase_event.set_address(Address(invalid_list.back()->get_physical_address(), BLOCK));
        if (ftl->controller.issue(erase_event) == FAILURE) {
            assert(false);
        }
        event.incr_time_taken(erase_event.get_time_taken());

        free_list.push_back(invalid_list.back());
        invalid_list.pop_back();

        num_to_erase--;
        ftl->controller.stats.numFTLErase++;
    }

    num_insert_events++;

    if (FTL_IMPLEMENTATION == IMPL_DFTL || FTL_IMPLEMENTATION == IMPL_BIMODAL)
    {

        ActiveByCost::iterator it = active_cost.get<1>().end();
        --it;


        while (num_to_erase != 0 && (*it)->get_pages_invalid() > 0 && (*it)->get_pages_valid() == BLOCK_SIZE)
        {
            if (current_writing_block != (*it)->physical_address)
            {
                //printf("erase p: %p phy: %li ratio: %i num: %i\n", (*it), (*it)->physical_address, (*it)->get_pages_invalid(), num_to_erase);
                Block *blockErase = (*it);

                // Let the FTL handle cleanup of the block.
                ftl->cleanup_block(event, blockErase);

                // Create erase event and attach to current event queue.
                Event erase_event = Event(ERASE, event.get_logical_address(), 1, event.get_start_time());
                erase_event.set_address(Address(blockErase->get_physical_address(), BLOCK));

                // Execute erase
                if (ftl->controller.issue(erase_event) == FAILURE) {
                    assert(false);
                }

                free_list.push_back(blockErase);

                event.incr_time_taken(erase_event.get_time_taken());

                ftl->controller.stats.numFTLErase++;
            }

            it = active_cost.get<1>().end();
            --it;

            if (current_writing_block == (*it)->physical_address)
                --it;

            num_to_erase--;
        }
    }
}
コード例 #29
0
ファイル: Block.cpp プロジェクト: rainloader/eclipse
Block Block::getMovedBlock(short movingDirection){
	Block movedBlock = *this;
	movedBlock.move(movingDirection);
	return movedBlock;
}
コード例 #30
0
ファイル: Join.cpp プロジェクト: chipitsine/ClickHouse
void Join::joinGetImpl(Block & block, const String & column_name, const Maps & maps_) const
{
    joinBlockImpl<ASTTableJoin::Kind::Left, ASTTableJoin::Strictness::Any>(
        block, {block.getByPosition(0).name}, {}, {sample_block_with_columns_to_add.getByName(column_name)}, maps_);
}