zoukankan      html  css  js  c++  java
  • PostgreSQL 源码解读 node的模拟实现

     

    node的实现是PostgreSQL的查询解析的基础,实现的关键是两个宏,makeNode和newNode。其他节点继承自Node节点,如果增加新的结构体,需要添加NodeTag中添加对应的枚举值,并在equal和nodetoString中添加对于的处理代码。当结构体少是很容易处理,如果结构体过多,维护会比较麻烦。PostgreSQL中大约有300个继承自node的结构体,写代码的人真是需要相当的勇气和毅力呀。

     

    #include <iostream>

    #include <string.h>

    #include <assert.h>

    #include <stdlib.h>

    #include <stdio.h>

    using namespace std;

     

    enum NodeTag

    {

        T_Stmt,

        T_Value

    };

     

    typedef struct Node

    {

        NodeTag type;

    }Node;

     

    Node *newNodeMacroHolder ;

    #define newNode(size, tag)

        (

             assert((size) >= sizeof(Node)),        /* need the tag, at least */

             newNodeMacroHolder = (Node *) malloc(size),

             newNodeMacroHolder->type = (tag),

             newNodeMacroHolder

        )

     

    #define makeNode(_type_) ((_type_ *)newNode(sizeof(_type_),T_##_type_))

    #define nodeTag(nodeptr) (((const Node *)(nodeptr))->type)

     

    typedef struct Stmt

    {

        NodeTag type;

        char *text;

    }Stmt;

    typedef struct Value

    {

        NodeTag type;

        long val;

    }Value;

     

    bool equal(void *a,void *b)

    {

        if(a == b)

            return true;

        if (a == NULL || b == NULL)

            return false;

        if(nodeTag(a) != nodeTag(b))

            return false;

     

        switch(nodeTag(a)){

            case T_Stmt:

                return strcmp(((const Stmt*)a)->text,((const Stmt *)b)->text)==0? true:false;

            case T_Value:

                return ((const Value *)a)->val==((const Value *)b)->val;

            default:

                cout<<"error:unknown type"<<endl;

        }

     

        return false;

    }

    char * nodetoString(void *obj)

    {

        char *r =(char *)malloc(1024);

     

        if (obj == NULL){

            strcpy(r,"<>");

        }

     

        switch(nodeTag(obj)){

            case T_Stmt:

                sprintf(r,"<Stmt:%s>",((const Stmt *)obj)->text);

                break;

            case T_Value:

                sprintf(r,"<Value:%ld>",((const Value *)obj)->val);

                break;

            default:

                strcpy(r,"<unknown node type>");

        }

     

        return r;

    }

     

    int main(int argc,char *argv[])

    {

        Stmt *s= makeNode(Stmt);

        if(s){

            char str[]="select * from a";

            s->text=str;

        }

            

        Stmt *t= makeNode(Stmt);

        if(t){

            char str[]="select * from b";

            t->text=str;

        }

        Value *v=makeNode(Value);

        if(v){

            v->val=100;

        }

     

        cout<<"t->text:"<<t->text<<endl;

        

        cout<<"equal:"<<equal(s,t)<<endl;

     

        cout<<nodetoString(t)<<endl;

     

        free(s);

        free(t);

        free(v);

        return 0;

    }

     

    如果准备使用C语言来实现node结构体的话,尤其是准备采用gcc编译的话,要注意将newNode的宏设置为

    /* 针对gcc版本的newNode */

    #define newNode(size, tag)

    ({    Node *_result;

        AssertMacro((size) >= sizeof(Node));/* 检测申请的内存大小,>>=sizeof(Node) */ 

        _result = (Node *) palloc0fast(size); /* 申请内存 */

        _result->type = (tag); /*设置TypeTag */ 

        _result; /*返回值*/

    })

     

    参见我的另一篇笔记《PostgreSQL源码解读 基础结构 node

  • 相关阅读:
    SAP Hybris使用recipe进行安装时,是如何执行ant命令的?
    实时电商数仓(三)之数据采集(二)搭建日志采集系统的集群(二)建立父工程
    实时电商数仓(一)之系统架构
    gdb 条件断点 + 多线程 +attach
    dpdk tx_pkt_burst rte_pktmbuf_free mbuf释放
    dpdk 网卡初始化 —— 收包
    dpdk 版本变动修改
    rte_mempool_get_priv
    mempool + ring test
    dpdk mempool debug
  • 原文地址:https://www.cnblogs.com/chenxueyou/p/3418494.html
Copyright © 2011-2022 走看看