高性能流媒体服务器-nebula之数据结构(3)--AVL树定时器

AVL树在nebula中的使用场景主要用于定时器的管理,对于线性增长的timestamp,经我们测试,AVL树比红黑数定时器在性能方面有一定的优势,尤其在WINDOWS平台表现得特别突出,所以我们采用AVL树作为nebula的定时器管理,下面是具体实现:

//
//  avltree.h
//  nebula
//
//  Created by yi.cheng on 16/5/7.
//  Copyright © 2016 kanshansoft. All rights reserved.
//

#ifndef avltree_h
#define avltree_h
/* no parent pointer */
template
   
   
    
     struct AVLNode{
    K               key;
    int             balance;
    struct AVLNode* l;
    struct AVLNode* r;
    struct AVLNode* p;
    inline AVLNode() : l(NULL), r(NULL), p(NULL), balance(0) {}
};

template
    
    
     
      class AVLTree {
    AVLTree(const AVLTree&);
    AVLTree& operator = (const AVLTree&);
public:
    AVLTree();
    int insert(AVLNode
     
     
      
      * node);
    void remove(AVLNode
      
      
       
       * node);
    AVLNode
       
       
         * find(const K& key); AVLNode 
        
          * find_min(); inline bool empty() const { return root == NULL; } private: AVLNode 
         
           * root; }; template 
          
            AVLTree 
           
             ::AVLTree() : root(NULL) {} template 
            
              int AVLTree 
             
               ::insert(AVLNode 
              
                * node) { AVLNode 
               
                 *parent = nullptr; //this ensures the parent of the root node is NULL; AVLNode 
                
                  **n = &root; node->l = node->r = node->p = nullptr; node->balance = 0; while ((*n)) { parent = *n; if(parent->key < node->key) n = &parent->r; else if(node->key < parent->key) n = &parent->l; else return -1; } *n = node; node->p = parent; avl_fixup_insert(root, node); return 0; } template 
                 
                   AVLNode 
                  
                    * AVLTree 
                   
                     ::find(const K& key) { auto p = root; while(p){ auto item = p; if(item->key < key) p = p->r; else if(key < item->key) p = p->l; else return item; } return nullptr; } template 
                    
                      inline AVLNode 
                     
                       * AVLTree 
                      
                        ::find_min() { AVLNode 
                       
                         * p = root; while(p->l){ p = p->l; } return p; } template 
                        
                          inline void AVLTree 
                         
                           ::remove(AVLNode 
                          
                            * node) { avl_del_node(root, node); } #include 
                           
                             #endif /* avltree_h */ // // avltree.cpp // nebula // // Created by yi.cheng on 16/5/7. // Copyright © 2016 kanshansoft. All rights reserved. // #include 
                            
                              #include 
                             
                               template 
                              
                                void __left_rotate(AVLNode 
                               
                                 *n, AVLNode 
                                
                                  *&root) { AVLNode 
                                 
                                   *parent = n->p; AVLNode 
                                  
                                    *right = n->r; if ((n->r = right->l)) n->r->p = n; n->p = right; right->l = n; right->p = parent; if (parent) { if (parent->l == n) parent->l = right; else parent->r = right; } else root = right; } template 
                                   
                                     void __right_rotate(AVLNode 
                                    
                                      *n, AVLNode 
                                     
                                       *&root) { AVLNode 
                                      
                                        *parent = n->p; AVLNode 
                                       
                                         *left = n->l; if ((n->l = left->r)) n->l->p = n; n->p = left; left->r = n; left->p = parent; if (parent) { if (parent->l == n) parent->l = left; else parent->r = left; } else root = left; } template 
                                        
                                          inline void avl_lr_rotate(AVLNode 
                                         
                                           *parent, AVLNode 
                                          
                                            *&r) { __left_rotate(parent->l, r); __right_rotate(parent, r); } template 
                                           
                                             inline void avl_rl_rotate(AVLNode 
                                            
                                              *parent, AVLNode 
                                             
                                               *&r) { __right_rotate(parent->r, r); __left_rotate(parent, r); } template 
                                              
                                                void avl_fixup_insert(AVLNode 
                                               
                                                 *&r, AVLNode 
                                                
                                                  *x) { AVLNode 
                                                 
                                                   *parent; AVLNode 
                                                  
                                                    *child; for(; (parent = x->p); x = parent){ if (parent->l == x) { parent->balance++; if (parent->balance == 0) break; if (parent->balance == 1) continue; //rotate if (x->balance == 1) { //LL x->balance = 0; parent->balance = 0; __right_rotate(parent, r); break; } //LR, x->balance == -1 child = x->r; parent->balance = x->balance = 0; if (child->balance == 1) parent->balance = -1; else if (child->balance == -1) x->balance = 1; child->balance = 0; avl_lr_rotate(parent, r); break; } else { parent->balance--; if (parent->balance == 0) break; if (parent->balance == -1) continue; //rotate //assert(parent->balance == -2); if (x->balance == -1) { x->balance = parent->balance = 0; __left_rotate(parent, r); break; } //RL, x->balance = 1 child = x->l; parent->balance = x->balance = 0; if (child->balance == -1) parent->balance = 1; else if (child->balance == 1) x->balance = -1; child->balance = 0; avl_rl_rotate(parent, r); break; } } } // x's balance is to be decreased // left == true child is left, left == false, child is right template 
                                                   
                                                     void avl_fixup_del(AVLNode 
                                                    
                                                      *&r, AVLNode 
                                                     
                                                       *x, bool left) { AVLNode 
                                                      
                                                        *parent; AVLNode 
                                                       
                                                         *child; AVLNode 
                                                        
                                                          *gc; for(;x;x=parent){ parent = x->p; if (left) { x->balance--; if (x->balance == -1) break; if (parent && parent->r == x) left = false; if (x->balance == 0) continue; // x's balance is -1, now to be -2, so should rotate. child = x->r; //assert(x->balance == -2 && child); if (child->balance == 0) { x->balance = -1; child->balance = 1; __left_rotate(x, r); break; } if (child->balance == -1) { x->balance = child->balance = 0; __left_rotate(x, r); continue; } gc = child->l; //child 's balance == 1 //assert(child->balance == 1 && gc); x->balance = child->balance = 0; if(gc->balance == -1) x->balance = 1; else if(gc->balance == 1) child->balance = -1; gc->balance = 0; avl_rl_rotate(x, r); } else { x->balance++; if (x->balance == 1) break; if (parent && parent->l == x) left = true; if (x->balance == 0) continue; child = x->l; //assert(x->balance == 2 && child); if (child->balance == 0) { x->balance = 1; child->balance = -1; __right_rotate(x, r); break; } if (child->balance == 1) { x->balance = child->balance = 0; __right_rotate(x, r); continue; } gc = child->r; //assert(child->balance == -1 && gc); x->balance = child->balance = 0; if(gc->balance == 1) x->balance = -1; else if(gc->balance == -1) child->balance = 1; gc->balance = 0; avl_lr_rotate(x, r); } } } template 
                                                         
                                                           void avl_del_node(AVLNode 
                                                          
                                                            *&r, AVLNode 
                                                           
                                                             *n) { AVLNode 
                                                            
                                                              *parent; AVLNode 
                                                             
                                                               *child; AVLNode 
                                                              
                                                                *target; bool left = false; target = parent = n->p; if (!n->l) child = n->r; else if (!n->r) child = n->l; else { //both n->l and n->r are not nil AVLNode 
                                                               
                                                                 *x = n->r; AVLNode 
                                                                
                                                                  *xp; while (x->l) x = x->l; child = x->r; xp = x->p; if (parent) { if (parent->l == n) parent->l = x; else parent->r = x; } else r = x; x->p = parent; // x->l = n->l; n->l->p = x; x->balance = n->balance; if (xp != n) { //n->r has no left child if (child) child->p = xp; xp->l = child; x->r = n->r; n->r->p = x; target = xp; left=true; } else{ target = x; left = false; } goto fixup; } if (parent) { if (parent->l == n) { parent->l = child; left = true; } else { parent->r = child; left = false; } } else r = child; if (child) child->p = parent; fixup: if (r) avl_fixup_del(r, target, left); n->p = n->l = n->r = NULL; } 
                                                                 
                                                                
                                                               
                                                              
                                                             
                                                            
                                                           
                                                          
                                                         
                                                        
                                                       
                                                      
                                                     
                                                    
                                                   
                                                  
                                                 
                                                
                                               
                                              
                                             
                                            
                                           
                                          
                                         
                                        
                                       
                                      
                                     
                                    
                                   
                                  
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值