首页 > 其他分享 >spdy_header

spdy_header

时间:2023-05-23 16:32:43浏览次数:32  
标签:spdy Node iterator Headers next header key


spdy_header: 一个工具类,代表着http header的数据结构。


<1> 因为http header本身的key-value特性,因此使用了hashMap来保存httpheader, key是header的名称,而value是header的内容。

对于碰撞,则采用了拉链法来解决,hashMap的bucket的尺寸由HTABLE_SIZE来编译期决定。



<2> 采用的hash算法比较简单,简单的字符串尺寸不断位移,在得到hval以后,和HTABLE_SIZE取余来得到bucket位置,其中,取余操作直接使用了为操作 havl&(HTABLE_SIZE-1), 效率上高一点。



<3> 每个单独的header作为Node存在, Node保存了此header的名称(key)和内容(value), 因为Node本身不在外边使用,因此直接作为了Headers的一个内部类,其只存在与本模块内供内部使用。



<4>于Node类似,Headers自己的iterator作为一个内部实现类存在,继承实现于spdy_header.h文件(也就是向外部开放的接口)的HeaderIterotor类,HeaderIterotor其实是一个接口类,本身是一个虚类,所有的方法都是纯虚汗数(virtual XXmethod() = 0)。



<5>因为实际的Node被保存在Headers类中,因此HeaderIterator的key和value都只是指向相应Node的key和value的引用(指针)罢了。



<6>因为Iterator会直接操作Headers中的成员,因此Headers内部的Iterator类是Headers的友元,但因为iterator本身是在Headers内部实现定义的,因此还是可以视为封装的。



<7>Headers对象本身维护一个HeaderIterator的引用(指针),这样在对Headers对象进行有关iterator的操作时,才有的放矢,比如:


get_iterator(), reset_iterator(), HeaderIterator对象 和 Headers对象是一种互相引用的关系,严格说,应该是Headers包含了一个HeaderIterator对象(在code中也有体现,iterator实际是在Headers的get_iterator()中new出来的)。



<8>Iterator的几个外部方法:next(), erase(),reset()。



<9>Headers的几个内部操作方法:


find() 单纯的查找key


find_add() 查找key,如果不存在,那么添加一个。


free_node(), 名称应该是free_node_list,因为其实现是递归的将某个node及其之后的所有通过next链接的node都删掉。


几个外部操作方法:


<10>Headers内部的Iterator类:

insert( Node *n ), 直接将此node插入到hash拉链的第一个 

 add(const Headers *), 将另外一个Headers的所有内容加入 

 add(const std::string &key, const std::string &val, char delim = '\0') 

 为http header量身定制,因为header内容其实容许存在多个值,用delim隔开,内部先使用find_add, 如果之前此key不存在,那么直接添加,否则,在已有的基础上加上delim和新的内容 

 add_first( const std::string &key, const std::string &val, char delim = '\0' ) 

 同上,不同的是,这次的内容加在原来内容的前边,利用string的insert实现 

 remove( const std::string &key ): 

 删除某个key对应的所有node(其实就是某个header), 在进行删除操作时, 

 采用了修改指向next的指针的内容的方法: 

 Node **pn = &htable[hval & (HTABLE_SIZE-1)]; 

     while(Node * curNodep = *pn) { 

         if ( curNodep->hval == hval && curNodep->key == key) { 

             *pn = curNodep->next; 

             delete curNodep; 

             _nelems--; 

             break; 

         } 

         pn = &curNodep->next; 

      // pn是指向Node的next的指针,在进行删除以后, 

         //将后面的元素重新链接起来时,只需把当前的pn所指的next指针 修改为指向 next指向的对象的next即可. 

     } 

 get_iterator(bool split) 

 获取Headers所属的iterator, split表示是否将某个header的多个值当成单独的成员看待。


因为Headers没有将Iterator暴露,并且Headers本身有一些修改iterator的方法,因此Headers也作为Iterator的一个friend class,


iterator在构造时就要传入一个Headers的指针来表示绑定关系。



<11>Iterator类有两个next方法:


next(): 表示前进到下一个Node(Header),如果某个hashbucket的node全部遍历完,那么就到下一个hash bucket,iterator的off变量标示当前的bucket位置。


next_sub():表示前进到header的下一个value(前面说过,一个header可能是多值的), last_pos标示上一个值结束的位置+1,每次从last_pos开始查找下一个值, 将iterator的value指针指向此值,Iterator内部有一个string类的substr,其内部保存的就是当前的header的当前遍历到的值,value实际指向的是substr。



<12>Iterator的reset():


其实就是将此iterator无效化,将current设为NULL,表示此iterator没有依附于任何的Node上,因此也无从取值和修改。



<13>Iterator的erase():


同Headers的remove(), 将current所指向的Node从Headers中拿去,因为都是指针,所以直接用某个Node的地址是否和current指针的值相同做判断,因为只保存了当前指向的Node,而Node的上一个成员并没有保存,因此在删除时还是需要遍历某个buckey的Node链。


标签:spdy,Node,iterator,Headers,next,header,key
From: https://blog.51cto.com/u_9420214/6333327

相关文章

  • spdy_zlib
    spdy_zlib:工具类,用于对数据进行deflate/gzip压缩,本身是对zlib库的定制化包装:<1>采用了头文件定义接口,实际实现类则通过继承此接口类在cc文件中定义,对外封闭。通过gz*get_context()获得可用的GZ对象(实际是实现类gzContextImpl的对象)<2>3个操......
  • spdy_buffer
    spdy_binary_buffer:工具类,作用就是一个可以自动扩容和内存空间回收的buffer(主要用来保存http和spdy传输的内容),单位为字节(类型为unsignedchar,因为字符集的值都是>=0的)<1>几个关键的属性:(1)unsignedchar*buffer:指向保存内容的那部分内存的开......
  • el-table的header-row-class-name或者row-class-name不生效的解决办法?
    思路如果使用的node脚手架,你的style标签长这样:<stylescoped></style>,那么只需要在给header-row-class-name或者row-class-name指定的css类上做个样式穿透。解决办法如:<el-table row-class-name="table-row-class"></el-table><stylescoped> /deep/.table-row-clas......
  • ant-design-vue中,如何将固定头部(layout-header)中的menu-item元素移动到右边
    官方的文档显示的都是左边,提供的API也没有移动到右边的功能 在ant-design-vue的群里面问了,然后又去各种问。有人建议可以用row和col来解决,也是可以,但是为了保持格式完整性,最好是在menu中去修改,不然,按键和其他按键不一样,很麻烦。去ant-design(ant-design-vue算是ant-design的分......
  • Nginx中add_header和proxy_set_header的区别
    一、proxy_set_header和add_header的区别 proxy_set_header是nginx设置请求头给上游服务器,add_header是nginx设置响应头信息给浏览器。1.1proxy_set_header 语法格式: proxy_set_headerfieldvalue; value值可以是包含文本、变量或者它们的组合。......
  • blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on th
    现在的浏览器出于安全策略的限制,都是不允许跨域的,但是开发的时候经常需要一些别的域的接口,特别是一些接口不是自己能控制的时候,往往会造成开发困难。今天无意中知道了,chrome浏览器可以通过设置为可跨域,解决跨域问题,从而在本地进行开发工作下面我就介绍谷歌浏览器新老版本各自的......
  • SpringCloud gateway HttpHeadersFilters
    HttpHeadersFilter在将请求发送到下游之前应用于请求,例如在NettyRoutingFilter中。1、ForwardedHeadersFilterForwardedHeadersFilter创建一个Forwarded标头以发送到下游服务。它将当前请求的Host标头、scheme和端口添加到任何现有的Forwarded标头中。2、RemoveHopByHopH......
  • MFC-GetHeaderCtrl获取列头指针
     CHeaderCtrl*phead=mylist4.GetHeaderCtrl();   ......
  • Feign远程调用会丢失header信息,如果设置远程调用的header信息
    场景:订单模块需要查询在购物车模块的商品信息,但是在购物车模块中存在两种购物车,一个是登录的用户的购物车,一个是没有登录的零时用户的购物车,如果用户已经的登录,我们就将用户的信息放入session中,我们通过创建一个拦截器进行判断用户是否进行登录,如果登陆了,就将用户的信息放入Threa......
  • 新项目删除SceneDelegate以及创建PrefixHeader文件
    1.新项目删除SceneDelegate删除SceneDelegate文件info.plist文件中删除ApplicationSceneManifest中的item删除SceneDelegate在AppDelegate中的代理在AppDelegate.h添加window小问题:2.新项目plist文件的移动buildSeting里搜索info.plistFile设置路径3.......