Linux网络编程--定时器之时间堆
2016-03-10 15:40
507 查看
相比较时间轮,时间堆的效率更高,主要利用最小堆的思想实现。
具体实现过程如下:
#ifndef intIME_HEAP
#define intIME_HEAP
#include <iostream>
#include <netinet/in.h>
#include <time.h>
using std::exception;
#define BUFFER_SIZE 64
class heap_timer;
struct client_data
{
sockaddr_in address;
int sockfd;
char buf[ BUFFER_SIZE ];
heap_timer* timer;
};
class heap_timer
{
public:
heap_timer( int delay )
{
expire = time( NULL ) + delay;
}
public:
time_t expire;
void (*cb_func)( client_data* );
client_data* user_data;
};
class time_heap
{
public:
time_heap( int cap ) throw ( std::exception )
: capacity( cap ), cur_size( 0 )
{
array = new heap_timer* [capacity];
if ( ! array )
{
throw std::exception();
}
for( int i = 0; i < capacity; ++i )
{
array[i] = NULL;
}
}
time_heap( heap_timer** init_array, int size, int capacity ) throw ( std::exception )
: cur_size( size ), capacity( capacity )
{
if ( capacity < size )
{
throw std::exception();
}
array = new heap_timer* [capacity];
if ( ! array )
{
throw std::exception();
}
for( int i = 0; i < capacity; ++i )
{
array[i] = NULL;
}
if ( size != 0 )
{
for ( int i = 0; i < size; ++i )
{
array[ i ] = init_array[ i ];
}
for ( int i = (cur_size-1)/2; i >=0; --i )
{
percolate_down( i );
}
}
}
~time_heap()
{
for ( int i = 0; i < cur_size; ++i )
{
delete array[i];
}
delete [] array;
}
public:
void add_timer( heap_timer* timer ) throw ( std::exception )
{
if( !timer )
{
return;
}
if( cur_size >= capacity )
{
resize();
}
int hole = cur_size++;
int parent = 0;
for( ; hole > 0; hole=parent )
{
parent = (hole-1)/2;
if ( array[parent]->expire <= timer->expire )
{
break;
}
array[hole] = array[parent];
}
array[hole] = timer;
}
void del_timer( heap_timer* timer )
{
if( !timer )
{
return;
}
// lazy delelte
timer->cb_func = NULL;
}
heap_timer* top() const
{
if ( empty() )
{
return NULL;
}
return array[0];
}
void pop_timer()
{
if( empty() )
{
return;
}
if( array[0] )
{
delete array[0];
array[0] = array[--cur_size];
percolate_down( 0 );
}
}
void tick()
{
heap_timer* tmp = array[0];
time_t cur = time( NULL );
while( !empty() )
{
if( !tmp )
{
break;
}
if( tmp->expire > cur )
{
break;
}
if( array[0]->cb_func )
{
array[0]->cb_func( array[0]->user_data );
}
pop_timer();
tmp = array[0];
}
}
bool empty() const { return cur_size == 0; }
private:
void percolate_down( int hole )
{
heap_timer* temp = array[hole];
int child = 0;
for ( ; ((hole*2+1) <= (cur_size-1)); hole=child )
{
child = hole*2+1;
if ( (child < (cur_size-1)) && (array[child+1]->expire < array[child]->expire ) )
{
++child;
}
if ( array[child]->expire < temp->expire )
{
array[hole] = array[child];
}
else
{
break;
}
}
array[hole] = temp;
}
void resize() throw ( std::exception )
{
heap_timer** temp = new heap_timer* [2*capacity];
for( int i = 0; i < 2*capacity; ++i )
{
temp[i] = NULL;
}
if ( ! temp )
{
throw std::exception();
}
capacity = 2*capacity;
for ( int i = 0; i < cur_size; ++i )
{
temp[i] = array[i];
}
delete [] array;
array = temp;
}
private:
heap_timer** array;
int capacity;
int cur_size;
};
#endif
具体实现过程如下:
#ifndef intIME_HEAP
#define intIME_HEAP
#include <iostream>
#include <netinet/in.h>
#include <time.h>
using std::exception;
#define BUFFER_SIZE 64
class heap_timer;
struct client_data
{
sockaddr_in address;
int sockfd;
char buf[ BUFFER_SIZE ];
heap_timer* timer;
};
class heap_timer
{
public:
heap_timer( int delay )
{
expire = time( NULL ) + delay;
}
public:
time_t expire;
void (*cb_func)( client_data* );
client_data* user_data;
};
class time_heap
{
public:
time_heap( int cap ) throw ( std::exception )
: capacity( cap ), cur_size( 0 )
{
array = new heap_timer* [capacity];
if ( ! array )
{
throw std::exception();
}
for( int i = 0; i < capacity; ++i )
{
array[i] = NULL;
}
}
time_heap( heap_timer** init_array, int size, int capacity ) throw ( std::exception )
: cur_size( size ), capacity( capacity )
{
if ( capacity < size )
{
throw std::exception();
}
array = new heap_timer* [capacity];
if ( ! array )
{
throw std::exception();
}
for( int i = 0; i < capacity; ++i )
{
array[i] = NULL;
}
if ( size != 0 )
{
for ( int i = 0; i < size; ++i )
{
array[ i ] = init_array[ i ];
}
for ( int i = (cur_size-1)/2; i >=0; --i )
{
percolate_down( i );
}
}
}
~time_heap()
{
for ( int i = 0; i < cur_size; ++i )
{
delete array[i];
}
delete [] array;
}
public:
void add_timer( heap_timer* timer ) throw ( std::exception )
{
if( !timer )
{
return;
}
if( cur_size >= capacity )
{
resize();
}
int hole = cur_size++;
int parent = 0;
for( ; hole > 0; hole=parent )
{
parent = (hole-1)/2;
if ( array[parent]->expire <= timer->expire )
{
break;
}
array[hole] = array[parent];
}
array[hole] = timer;
}
void del_timer( heap_timer* timer )
{
if( !timer )
{
return;
}
// lazy delelte
timer->cb_func = NULL;
}
heap_timer* top() const
{
if ( empty() )
{
return NULL;
}
return array[0];
}
void pop_timer()
{
if( empty() )
{
return;
}
if( array[0] )
{
delete array[0];
array[0] = array[--cur_size];
percolate_down( 0 );
}
}
void tick()
{
heap_timer* tmp = array[0];
time_t cur = time( NULL );
while( !empty() )
{
if( !tmp )
{
break;
}
if( tmp->expire > cur )
{
break;
}
if( array[0]->cb_func )
{
array[0]->cb_func( array[0]->user_data );
}
pop_timer();
tmp = array[0];
}
}
bool empty() const { return cur_size == 0; }
private:
void percolate_down( int hole )
{
heap_timer* temp = array[hole];
int child = 0;
for ( ; ((hole*2+1) <= (cur_size-1)); hole=child )
{
child = hole*2+1;
if ( (child < (cur_size-1)) && (array[child+1]->expire < array[child]->expire ) )
{
++child;
}
if ( array[child]->expire < temp->expire )
{
array[hole] = array[child];
}
else
{
break;
}
}
array[hole] = temp;
}
void resize() throw ( std::exception )
{
heap_timer** temp = new heap_timer* [2*capacity];
for( int i = 0; i < 2*capacity; ++i )
{
temp[i] = NULL;
}
if ( ! temp )
{
throw std::exception();
}
capacity = 2*capacity;
for ( int i = 0; i < cur_size; ++i )
{
temp[i] = array[i];
}
delete [] array;
array = temp;
}
private:
heap_timer** array;
int capacity;
int cur_size;
};
#endif
相关文章推荐
- http://www.dewen.net.cn/q/15328/问个正则表达式 贪婪 和 不匹配某个字符串问题
- 【Networking】网络编程常见问题汇总
- JavaWeb知识总结——Http协议
- 网络层2
- 网络层1
- http://www.dewen.net.cn/q/15749/PHP求数组值相加(可重复)等于某值的所有组合
- 网络基础知识5
- 网络基础知识3
- 网络基础知识2
- http://www.dewen.net.cn/q/15800/php如何生成十进制00到20之间的2位随机数
- http://www.dewen.net.cn/q/15807/java byte 疑问
- http head
- Linux网络编程--定时器之时间轮
- 网络基础知识1
- http://www.dewen.net.cn/q/16007/mysql查询如何先排序再分组呢
- http://www.dewen.net.cn/q/16042/jquery fadeIn和fadeOut问题
- http://www.dewen.net.cn/q/17095/SQL:用一条SQL语句统计出符合条件的内容
- http://www.dewen.net.cn/q/16222/C++排序中的sort函数第三个参数的疑问
- TCP/IP协议 1 ----实验楼转
- http://www.dewen.net.cn/q/15720/这样的情况一个sql语句怎么写