Ejemplo n.º 1
0
void HashGraph::RefreshVertices(unsigned minCount)
{
#pragma omp parallel for
    for (int64 i = 0; i < (int64)table_size; ++i)
    {
        HashNode *node = table[i];
        HashNode *prev = NULL;
        while (node != NULL)
        {
            if (node->IsDead() || node->Count() < minCount)
            {
#pragma omp atomic
                --num_nodes;
                if (prev == NULL)
                {
                    table[i] = node->next;
                    FreeNode(node, omp_get_thread_num());
                    node = table[i];
                }
                else
                {
                    prev->next = node->next;
                    FreeNode(node, omp_get_thread_num());
                    node = prev->next;
                }
            }
            else
            {
                node->ClearStatus();
                prev = node;
                node = prev->next;
            }
        }
    }
}
Ejemplo n.º 2
0
	void resize() {
		int new_length = 4;
		while(new_length < elems_) {
			new_length <<= 1;
		}
		HashNode** new_list = new HashNode*[new_length];
		memset(new_list, 0, sizeof(new_list[0]) * new_length);
		int count = 0;

		for(int i=0; i<length_; ++i) {
			HashNode* now = list_[i];
			while(now != NULL) {
				HashNode* next = now->next_hash;
				Slice key = now->key();
				int hash = now->hash;
				HashNode** ptr = &new_list[hash & (new_length - 1)];

				now->next_hash = *ptr;
				*ptr = now;
				now = next;
				count++;
			}
		}
		assert(elems_ == count);
		delete[] list_;
		list_ = new_list;
		length_ = new_length;
	}
Ejemplo n.º 3
0
void HashGraph::ClearGraph()
{
    for (unsigned i = 0; i < table_size; ++i)
    {
        for (HashNode *node = table[i]; node != NULL; node = node->next)
        {
            node->Clear();
            node->SetCount(1);
        }
    }
    num_edges = 0;
}
Ejemplo n.º 4
0
void HashGraph::AddAllEdges()
{
    num_edges = 0;
#pragma omp parallel for
    for (int64 i = 0; i < (int64)table_size; ++i)
    {
        for (HashNode *node = table[i]; node; node = node->next)
        {
            node->SetInEdges(15);
            node->SetOutEdges(15);
        }
    }
}
Ejemplo n.º 5
0
void GrCCPathCache::evict(const GrCCPathCache::Key& key, GrCCPathCacheEntry* entry) {
    if (!entry) {
        HashNode* node = fHashTable.find(key);
        SkASSERT(node);
        entry = node->entry();
    }
    SkASSERT(*entry->fCacheKey == key);
    SkASSERT(!entry->hasBeenEvicted());
    entry->fCacheKey->markShouldUnregisterFromPath();  // Unregister the path listener.
    entry->releaseCachedAtlas(this);
    fLRU.remove(entry);
    fHashTable.remove(key);
}
Ejemplo n.º 6
0
double HashGraph::AverageCoverage()
{
    long long sum = 0;
    uint64 valid = 0;
    for (int64 i = 0; i < table_size; ++i)
    {
        for (HashNode *node = table[i]; node; node = node->next)
        {
            sum += node->Count();
            ++valid;
        }
    }

    return 1.0 * sum / valid;
}
int CTECHashTable<Type>:: findPosition(HashNode<Type> currentNode){
	int position = 0;

	position = currentNode.getKey()%capacity;

	return position;
}
Ejemplo n.º 8
0
double HashGraph::MedianCoverage()
{
    vector<int> v;
    v.reserve(num_nodes);
    for (int64 i = 0; i < table_size; ++i)
    {
        for (HashNode *node = table[i]; node; node = node->next)
        {
            v.push_back(node->Count());
        }
    }

    nth_element(v.begin(), v.begin() + v.size()/2, v.end());

    return *(v.begin() + v.size()/2);
}
Ejemplo n.º 9
0
	HashNode* insert(const Slice& key, int& hit_id, int& rep_id) {
		HashNode* e = reinterpret_cast<HashNode*>(malloc(sizeof(HashNode) - 1 + key.size()));
		e->key_length = key.size();
		e->hash = hash_slice(key);
		memcpy(e->key_data, key.data(), key.size());

		lru_append(e);
		HashNode* old = table_.insert(e);

		if(old != NULL) {
			//命中缓存
			e->cache_id = old->cache_id;

			hit_id = e->cache_id;
			rep_id = -1;

			lru_remove(old);
			lru_release(old);

			//update hit ratio
			hit_cnt++;
		}
		else {
			//没有命中缓存
			hit_id = -1;

			//如果当前的缓存数量超过capacity,把lru_后面的那个缓存单元淘汰掉
			if(table_.size() > capacity_) {
				HashNode* cursor = lru_.next;
				lru_remove(cursor);
				table_.remove(cursor->key(), cursor->hash);

				e->cache_id = cursor->cache_id;
				lru_release(cursor);
			}
			else {
				e->cache_id = last_id++;  //TODO 会无限增长?
			}

			rep_id = e->cache_id;

			//update hit ratio
			set_cnt++;
		}

		return e;
	}
Ejemplo n.º 10
0
long HashTable<Type> :: findPosition(Type data)
{
    long insertedPosition;
    unsigned long address =(long)&data;
    insertedPosition = address % capacity;
    HashNode<Type>* indexPointer = front;
    for (long index = 0; index < insertedPosition; index++)
    {
        indexPointer = indexPointer->getNode();
    }
if (indexPointer->hasStuffed())
{
    insertedPosition = handleCollision(data, insertedPosition);
}
    
    return insertedPosition;
}
Ejemplo n.º 11
0
int HashTable<Type> :: findPosition(HashNode<Type> currentNode)
{
    //We are going "hash" the key of the HashNode to find its value.
    int position = 0;
    
    position = currentNode.getKey() % capacity;
    return position;
}
Ejemplo n.º 12
0
int CTECHashTable<Type>::findTablePosition(HashNode<Type> currentNode)
{
	//We are going to "hash" the key of the hashnode to find its storage spot.
	int position = 0;

	position = currentNode.getKey() % tableCapacity;

	return position;
}
Ejemplo n.º 13
0
void HashGraph::RefreshEdges()
{
    num_edges = 0;
#pragma omp parallel for
    for (int64 i = 0; i < (int64)table_size; ++i)
    {
        for (HashNode *node = table[i]; node; node = node->next)
        {
            KmerNodeAdapter curr(node);
            for (int strand = 0; strand < 2; ++strand)
            {
                Kmer kmer;
                curr.GetKmer(kmer);
                unsigned edges = curr.OutEdges();
                for (int x = 0; x < 4; ++x)
                {
                    if (edges & (1 << x))
                    {
                        Kmer next = kmer;
                        next.AddRight(x);
                        if (GetNode(next) == NULL)
                            curr.RemoveOutEdge(x);
                        else
                        {
#pragma omp atomic
                            ++num_edges;
                        }
                    }
                }

                curr.ReverseComplement();
            }

            if (node->kmer.IsPalindrome())
            {
                unsigned edges = node->InEdges() | node->OutEdges();
                node->SetInEdges(edges);
                node->SetOutEdges(edges);
            }
        }
    }

    num_edges >>= 1;
}
bool CTECHashTable<Type>:: contains(HashNode<Type> currentNode){
	bool isInTable = false;

	int possibleLocation = findPosition(currentNode);

	while(internalStorage[possibleLocation] != nullptr && !isInTable){
		if(internalStorage[possibleLocation] == currentNode.getValue()){
			isInTable = true;
		}
		possibleLocation = (possibleLocation + 1) % capacity;
	}

	return isInTable;
}
bool CTECHashTable<Type>:: remove(HashNode<Type> currentNode){
	bool hasBeenRemoved = false;
	int possibleLocation = findPosition(currentNode);

	if(contains(currentNode)){
		while(internalStorage[possibleLocation] != nullptr && !hasBeenRemoved){
			if(internalStorage[possibleLocation] == currentNode.getValue()){
				hasBeenRemoved = true;
				internalStorage[possibleLocation] = nullptr;
			}
			possibleLocation = (possibleLocation + 1) % capacity;
		}
	}
	return hasBeenRemoved;
}
Ejemplo n.º 16
0
bool CTECHashTable<Type>::contains(HashNode<Type> currentNode)
{
	bool isInTable = false;

	int index = findPosition(currentNode);
	while (internalStorage[index] != nullptr&& !isInTable)
	{
		if(internalStorage[index]->getValue() == currentNode.getValue())
		{
			isInTable = true;
		}
		else
		{
			index = (index + 1) % capacity;
		}
	}

	return isInTable;
}
Ejemplo n.º 17
0
bool HashTable<Type> :: contains(HashNode<Type> currentNode)
{
    bool wasRemoved = false;
  
        int index = findPosition(currentNode);
        while(internalStorage[index] != nullptr && !wasRemoved)
        {
            if(internalStorage[index]->getValue() == currentNode.getValue())
            {
                wasRemoved = true;
                internalStorage[index] = nullptr;
                size--;
            }
            else
            {
                index = (index + 1) % capacity;
            }
        }
    
    return wasRemoved;
}
Ejemplo n.º 18
0
int64 HashGraph::Assemble(vector<Contig> &contigs)
{
    contigs.resize(0);
    int tangle = 0;

    omp_lock_t lockContigs;
    omp_init_lock(&lockContigs);

#pragma omp parallel for
    for (int64 i = 0; i < (int64)table_size; ++i)
    {
        for (HashNode *node = table[i]; node != NULL; node = node->next)
        {
            if (!node->Lock(omp_get_thread_num()))
                continue;

            Contig contig;
            contig.SetContent(node->kmer, kmerLength);
            contig.sum_coverage = node->Count();
            contig.is_tangle = false;

            if (!node->kmer.IsPalindrome())
            {
                for (int strand = 0; strand < 2; ++strand)
                {
                    KmerNodeAdapter adp = GetNodeAdapter(contig.GetEndKmer());
                    KmerNodeAdapter next(NULL);

                    while (true)
                    {
                        if (!GetNextNodeAdapter(adp, next))
                            break;

                        if (next.GetLockID() == omp_get_thread_num() && IsLoop(contig, next))
                            break;

                        if (!next.LockPreempt(omp_get_thread_num()))
                            goto FAIL;

                        contig.AddNucleotide(BitOperation::bitToIndex[adp.OutEdges()]);
                        adp = next;
                        contig.sum_coverage += next.Count();
                    }

                    if (adp.OutDegree() == 0)
                        contig.is_tangle = true;
                    contig.ReverseComplement();
                }
            }

            if (contig.is_tangle)
            {
#pragma omp atomic
                ++tangle;
            }

            omp_set_lock(&lockContigs);
            contigs.push_back(contig);
            omp_unset_lock(&lockContigs);
FAIL:
            ;
        }
    }

    omp_destroy_lock(&lockContigs);

    ClearStatus();
    LogMessage("tangle %d total %d\n", tangle, contigs.size());

    return contigs.size();

}
Ejemplo n.º 19
0
int HashTable<Type> :: findTablePosition(HashNode<Type> currentNode)
{
    int position = 0;
    
    position = currentNode.getKey() % tableCapacity;
}
Ejemplo n.º 20
0
void parser_dump(mrb_state *mrb, mrb_ast_node *tree, int offset)
{
#ifdef ENABLE_STDIO
    if (!tree) return;
again:
    dump_prefix(offset);
    node_type n = tree->getType();
    mrb_ast_node *orig = tree;
    if(dynamic_cast<UpdatedNode *>(tree)==0)
        tree = tree->right();

    switch (n) {
        case NODE_BEGIN: parser_dump(mrb,(BeginNode *)orig,offset); break;

        case NODE_RESCUE: parser_dump(mrb,(RescueNode *)orig,offset); break;

        case NODE_ENSURE: parser_dump(mrb,(EnsureNode *)orig,offset); break;

        case NODE_LAMBDA:
            printf("NODE_LAMBDA:\n");
            goto block;

        case NODE_BLOCK:
            printf("NODE_BLOCK:\n");
block:
            parser_dump(mrb,(LambdaCommonNode *)orig,offset);
            break;

        case NODE_IF:
        {
            IfNode *in = (IfNode *)orig;
            printf("NODE_IF:\n");
            dump_prefix(offset+1);
            printf("cond:\n");
            parser_dump(mrb, in->cond(), offset+2); //tree->left()
            dump_prefix(offset+1);
            printf("then:\n");
            parser_dump(mrb, in->true_body(), offset+2); //tree->right()->left()
            if (in->false_body()) {
                dump_prefix(offset+1);
                printf("else:\n");
                parser_dump(mrb, in->false_body() , offset+2); //tree->right()->right()->left()
            }
        }
            break;

        case NODE_AND:
        {
            AndNode *an = (AndNode *)orig;
            printf("NODE_AND:\n");
            parser_dump(mrb, an->lhs(), offset+1);
            parser_dump(mrb, an->rhs(), offset+1);
        }
            break;

        case NODE_OR:
        {
            OrNode *an = (OrNode *)orig;
            printf("NODE_OR:\n");
            parser_dump(mrb, an->lhs(), offset+1);
            parser_dump(mrb, an->rhs(), offset+1);
        }
            break;

        case NODE_CASE:  {
            CaseNode *cn = (CaseNode *)orig;
            printf("NODE_CASE:\n");
            if (cn->switched_on()) {
                parser_dump(mrb, cn->switched_on(), offset+1);
            }
            tree = cn->cases();
            while (tree) {
                dump_prefix(offset+1);
                printf("case:\n");
                dump_recur(mrb, tree->left()->left(), offset+2);
                dump_prefix(offset+1);
                printf("body:\n");
                parser_dump(mrb, tree->left()->right(), offset+2);
                tree = tree->right();
            }
        }
            break;

        case NODE_WHILE:
        {
            WhileNode *n = (WhileNode *)orig;
            printf("NODE_WHILE:\n");
            dump_prefix(offset+1);
            printf("cond:\n");
            parser_dump(mrb, n->lhs(), offset+2);
            dump_prefix(offset+1);
            printf("body:\n");
            parser_dump(mrb, n->rhs(), offset+2);
        }
            break;

        case NODE_UNTIL:
        {
            UntilNode *n = (UntilNode *)orig;
            printf("NODE_UNTIL:\n");
            dump_prefix(offset+1);
            printf("cond:\n");
            parser_dump(mrb, n->lhs(), offset+2);
            dump_prefix(offset+1);
            printf("body:\n");
            parser_dump(mrb, n->rhs(), offset+2);
        }
            break;

        case NODE_FOR:
            printf("NODE_FOR:\n");
            dump_prefix(offset+1);
            parser_dump(mrb,(ForNode *)orig,offset);
            break;

        case NODE_SCOPE:
            printf("NODE_SCOPE:\n");
        {
            ScopeNode *ns = (ScopeNode *)orig;
            const tLocals &n2(ns->locals());

            if ( !n2.empty() ) {
                dump_prefix(offset+1);
                printf("local variables:\n");
                dump_prefix(offset+2);
                for(auto iter=n2.begin(); iter!=n2.end(); ++iter) {
                    if ( (iter+1) != n2.end() )
                        printf(", ");
                    printf("%s", mrb_sym2name(mrb, *iter));
                }
                printf("\n");
            }
            tree = ns->body();
        }
            offset++;
            goto again;

        case NODE_FCALL:
        case NODE_CALL:
        {
            CallCommonNode *cn = (CallCommonNode *)orig;
            printf("NODE_CALL:\n");
            parser_dump(mrb, cn->m_receiver, offset+1);
            dump_prefix(offset+1);
            printf("method='%s' (%d)\n",
                   mrb_sym2name(mrb, cn->m_method),
                   cn->m_method);
            CommandArgs *ca = cn->m_cmd_args;
            if (ca) {
                dump_prefix(offset+1);
                printf("args:\n");
                dump_recur(mrb, ca->m_args, offset+2);
                if (ca->m_blk) {
                    dump_prefix(offset+1);
                    printf("block:\n");
                    parser_dump(mrb, ca->m_blk, offset+2);
                }
            }
        }
            break;

        case NODE_DOT2:
        {
            printf("NODE_DOT2:\n");
            Dot2Node *nd = (Dot2Node *)orig;
            parser_dump(mrb, nd->lhs(), offset+1);
            parser_dump(mrb, nd->rhs(), offset+1);
        }
            break;

        case NODE_DOT3:
        {
            printf("NODE_DOT3:\n");
            Dot3Node *nd = (Dot3Node *)orig;
            parser_dump(mrb, nd->lhs(), offset+1);
            parser_dump(mrb, nd->rhs(), offset+1);
        }
            break;

        case NODE_COLON2:
        {
            Colon2Node *cn = (Colon2Node *)orig;
            printf("NODE_COLON2:\n");
            parser_dump(mrb, cn->m_val, offset+1);
            dump_prefix(offset+1);
            printf("::%s\n", mrb_sym2name(mrb, cn->m_sym));
        }
            break;

        case NODE_COLON3:{
            printf("NODE_COLON3:\n");
            dump_prefix(offset+1);
            Colon3Node *n = (Colon3Node *)orig;
            printf("::%s\n", mrb_sym2name(mrb, n->sym()));
        }
            break;

        case NODE_ARRAY:
            printf("NODE_ARRAY:\n");
            dump_recur(mrb, ((ArrayNode *)orig)->child(), offset+1);
            break;

        case NODE_HASH:
        {
            HashNode *nd = (HashNode *)orig;
            printf("NODE_HASH:\n");
            tree = nd->child();
            while (tree) {
                dump_prefix(offset+1);
                printf("key:\n");
                parser_dump(mrb, tree->left()->left(), offset+2);
                dump_prefix(offset+1);
                printf("value:\n");
                parser_dump(mrb, tree->left()->right(), offset+2);
                tree = tree->right();
            }
        }
            break;

        case NODE_SPLAT:
            printf("NODE_SPLAT:\n");
            parser_dump(mrb, ((SplatNode *)orig)->child(), offset+1);
            break;

        case NODE_ASGN:
        {
            AsgnNode *an = (AsgnNode *)orig;
            printf("NODE_ASGN:\n");
            dump_prefix(offset+1);
            printf("lhs:\n");
            parser_dump(mrb, an->lhs(), offset+2);
            dump_prefix(offset+1);
            printf("rhs:\n");
            parser_dump(mrb, an->rhs(), offset+2);
        }
            break;

        case NODE_MASGN:
        {
            printf("NODE_MASGN:\n");
            dump_prefix(offset+1);
            printf("mlhs:\n");
            MAsgnNode *mn = (MAsgnNode *)orig;
            mrb_ast_node *n2 = mn->lhs();

            if (n2->left()) {
                dump_prefix(offset+2);
                printf("pre:\n");
                dump_recur(mrb, n2->left(), offset+3);
            }
            n2 = n2->right();
            if (n2) {
                if (n2->left()) {
                    dump_prefix(offset+2);
                    printf("rest:\n");
                    if (n2->left() == (mrb_ast_node*)-1) {
                        dump_prefix(offset+2);
                        printf("(empty)\n");
                    }
                    else {
                        parser_dump(mrb, n2->left(), offset+3);
                    }
                }
                n2 = n2->right();
                if (n2) {
                    if (n2->left()) {
                        dump_prefix(offset+2);
                        printf("post:\n");
                        dump_recur(mrb, n2->left(), offset+3);
                    }
                }
            }
            dump_prefix(offset+1);
            printf("rhs:\n");
            parser_dump(mrb, mn->rhs(), offset+2);
        }
            break;

        case NODE_OP_ASGN: {
            OpAsgnNode *opasgn = static_cast<OpAsgnNode *>(tree);
            printf("NODE_OP_ASGN:\n");
            dump_prefix(offset+1);
            printf("lhs:\n");
            parser_dump(mrb, opasgn->lhs(), offset+2);
            dump_prefix(offset+1);
            printf("op='%s' (%d)\n", mrb_sym2name(mrb, opasgn->op_sym), opasgn->op_sym);
            parser_dump(mrb, opasgn->rhs(), offset+1);
            break;
        }
        case NODE_SUPER:
        {
            printf("NODE_SUPER:\n");
            SuperNode *x=(SuperNode *)orig;
            if (x->hasParams()) {
                dump_prefix(offset+1);
                printf("args:\n");
                dump_recur(mrb, x->args(), offset+2);
                if (x->block()) {
                    dump_prefix(offset+1);
                    printf("block:\n");
                    parser_dump(mrb, x->block(), offset+2);
                }
            }
        }
            break;

        case NODE_ZSUPER:
            printf("NODE_ZSUPER\n");
            break;

        case NODE_RETURN:
            printf("NODE_RETURN:\n");
            parser_dump(mrb, ((ReturnNode *)orig)->child(), offset+1);
            break;

        case NODE_YIELD:
            printf("NODE_YIELD:\n");
            dump_recur(mrb, ((YieldNode *)orig)->child(), offset+1);
            break;

        case NODE_BREAK:
            printf("NODE_BREAK:\n");
            parser_dump(mrb, ((BreakNode *)orig)->child(), offset+1);
            //parser_dump(mrb, tree, offset+1);
            break;

        case NODE_NEXT:
            printf("NODE_NEXT:\n");
            parser_dump(mrb, ((NextNode *)orig)->child(), offset+1);
            break;

        case NODE_REDO:
            printf("NODE_REDO\n");
            break;

        case NODE_RETRY:
            printf("NODE_RETRY\n");
            break;

        case NODE_LVAR:
        {
            LVarNode * lvar = (LVarNode *)orig;
            printf("NODE_LVAR %s\n", mrb_sym2name(mrb, lvar->sym()));
        }
            break;

        case NODE_GVAR:
        {
            GVarNode * gvar = (GVarNode *)orig;
            printf("NODE_GVAR %s\n", mrb_sym2name(mrb, gvar->sym()));
        }
            break;

        case NODE_IVAR:
        {
            IVarNode * ivar = (IVarNode *)orig;
            printf("NODE_IVAR %s\n", mrb_sym2name(mrb, ivar->sym()));
        }
            break;

        case NODE_CVAR:
        {
            CVarNode * cvar = (CVarNode *)orig;
            printf("NODE_CVAR %s\n", mrb_sym2name(mrb, cvar->sym()));
        }
            break;

        case NODE_CONST:
        {
            ConstNode * cvar = (ConstNode *)orig;
            printf("NODE_CONST %s\n", mrb_sym2name(mrb, cvar->sym()));
        }

            break;

        case NODE_MATCH:
            printf("NODE_MATCH:\n");
            dump_prefix(offset + 1);
            printf("lhs:\n");
            parser_dump(mrb, tree->left(), offset + 2);
            dump_prefix(offset + 1);
            printf("rhs:\n");
            parser_dump(mrb, tree->right(), offset + 2);
            break;

        case NODE_BACK_REF:
            printf("NODE_BACK_REF: $%c\n", ((BackRefNode *)orig)->m_ref);
            break;

        case NODE_NTH_REF:
            printf("NODE_NTH_REF: $%d\n", ((NthRefNode *)orig)->m_ref);
            break;

        case NODE_ARG:
        {
            ArgNode * var = (ArgNode *)orig;
            printf("NODE_ARG %s\n", mrb_sym2name(mrb, var->sym()));
        }
            break;

        case NODE_BLOCK_ARG:
        {

            printf("NODE_BLOCK_ARG:\n");
            parser_dump(mrb, ((BlockArgNode *)orig)->child(), offset+1);
        }
            break;

        case NODE_INT:
        {
            IntLiteralNode *int_lit = (IntLiteralNode *)orig;
            printf("NODE_INT %s base %d\n", int_lit->m_val, int_lit->m_base);
        }
            break;

        case NODE_FLOAT:
            printf("NODE_FLOAT %s\n", ((FloatLiteralNode *)orig)->m_val);
            break;

        case NODE_NEGATE:
            printf("NODE_NEGATE\n");
            parser_dump(mrb, ((NegateNode *)tree)->child(), offset+1);
            break;

        case NODE_STR:
        {
            StrNode *sn=(StrNode *)orig;
            printf("NODE_STR \"%s\" len %zu\n", sn->m_str, sn->m_length);
        }
            break;

        case NODE_DSTR:
        {
            DstrNode *dn = (DstrNode *)orig;
            printf("NODE_DSTR\n");
            dump_recur(mrb, dn->child(), offset+1);
        }
            break;

        case NODE_XSTR:
            printf("NODE_XSTR \"%s\" len %d\n", (char*)tree->left(), (int)(intptr_t)tree->right());
            break;

        case NODE_DXSTR: {
            DxstrNode *dn = (DxstrNode *)orig;
            printf("NODE_DXSTR\n");
            dump_recur(mrb, dn->child(), offset+1);
        }
            break;

        case NODE_REGX:
            printf("NODE_REGX /%s/%s\n", (char*)tree->left(), (char*)tree->right());
            break;

        case NODE_DREGX:
            printf("NODE_DREGX\n");
            dump_recur(mrb, tree->left(), offset+1);
            dump_prefix(offset);
            printf("tail: %s\n", (char*)tree->right()->right()->left());
            dump_prefix(offset);
            printf("opt: %s\n", (char*)tree->right()->right()->right());
            break;

        case NODE_SYM:
        {
            SymNode * cvar = (SymNode *)orig;
            printf("NODE_SYM :%s\n", mrb_sym2name(mrb, cvar->sym()));
        }
            break;

        case NODE_SELF:
            printf("NODE_SELF\n");
            break;

        case NODE_NIL:
            printf("NODE_NIL\n");
            break;

        case NODE_TRUE:
            printf("NODE_TRUE\n");
            break;

        case NODE_FALSE:
            printf("NODE_FALSE\n");
            break;

        case NODE_ALIAS:
        {
            AliasNode *an = (AliasNode *)orig;
            printf("NODE_ALIAS %s %s:\n",
                   mrb_sym2name(mrb, an->m_from),
                   mrb_sym2name(mrb, an->m_to));
        }
            break;

        case NODE_UNDEF:
            printf("NODE_UNDEF");
        {
            UndefNode *und((UndefNode *)tree);
            for(mrb_sym v : und->m_syms) {
                printf(" %s", mrb_sym2name(mrb, v));
            }
        }
            printf(":\n");
            break;

        case NODE_CLASS: {
            ClassNode *cn = static_cast<ClassNode *>(tree);
            printf("NODE_CLASS:\n");
            if (cn->receiver()->left() == (mrb_ast_node*)0) {
                dump_prefix(offset+1);
                printf(":%s\n", mrb_sym2name(mrb, sym(cn->receiver()->right())));
            }
            else if (cn->receiver()->left() == (mrb_ast_node*)1) {
                dump_prefix(offset+1);
                printf("::%s\n", mrb_sym2name(mrb, sym(cn->receiver()->right())));
            }
            else {
                parser_dump(mrb, cn->receiver()->left(), offset+1);
                dump_prefix(offset+1);
                printf("::%s\n", mrb_sym2name(mrb, sym(cn->receiver()->right())));
            }
            if (cn->super()) {
                dump_prefix(offset+1);
                printf("super:\n");
                parser_dump(mrb, cn->super(), offset+2);
            }
            dump_prefix(offset+1);
            printf("body:\n");
            parser_dump(mrb, cn->scope()->body(), offset+2);
            break;
        }

        case NODE_MODULE: {
            ModuleNode *cn = static_cast<ModuleNode *>(tree);
            printf("NODE_MODULE:\n");

            if (cn->receiver()->left() == (mrb_ast_node*)0) {
                dump_prefix(offset+1);
                printf(":%s\n", mrb_sym2name(mrb, sym(cn->receiver()->right())));
            }
            else if (cn->receiver()->left() == (mrb_ast_node*)1) {
                dump_prefix(offset+1);
                printf("::%s\n", mrb_sym2name(mrb, sym(cn->receiver()->right())));
            }
            else {
                parser_dump(mrb, cn->receiver(), offset+1);
                dump_prefix(offset+1);
                printf("::%s\n", mrb_sym2name(mrb, sym(cn->receiver()->right())));
            }
            dump_prefix(offset+1);
            printf("body:\n");
            parser_dump(mrb, cn->scope()->body(), offset+2);
            break;
        }
        case NODE_SCLASS: {
            printf("NODE_SCLASS:\n");
            SclassNode *scn((SclassNode *)tree);

            parser_dump(mrb, scn->scope(), offset+1);
//            dump_prefix(offset+1);
//            printf("body:\n");
//            parser_dump(mrb, scntree->right()->left()->right(), offset+2);
        }
            break;

        case NODE_DEF:
        {
            DefNode *dn = (DefNode *)orig;
            printf("NODE_DEF:\n");
            dump_prefix(offset+1);
            parser_dump(mrb,dn,offset);
        }
            break;

        case NODE_SDEF:
        {
            SdefNode *sn = (SdefNode *)orig;
            printf("NODE_SDEF:\n");
            parser_dump(mrb, sn->receiver(), offset+1);
            dump_prefix(offset+1);
            printf(":"); // prepend name with ':'
            parser_dump(mrb,sn,offset);
        }
            break;

        case NODE_POSTEXE:
            printf("NODE_POSTEXE:\n");
            parser_dump(mrb, ((PostExeNode *)orig)->child(), offset+1);
            break;

        case NODE_HEREDOC:{
            printf("NODE_HEREDOC:\n");
            HeredocNode *hdn((HeredocNode *)tree);

            parser_dump(mrb, hdn->contents()->doc->left(), offset+1);
        }
            break;

        default:
            printf("node type: %d (0x%x)\n", (int)n, (int)n);
            break;
    }
#endif
}