使用跳表实现定时器
使用的是redis中使用的跳表结构,直接从中迁移出来并修改。 通过跳表实现的时间轮,查询第一个数据的时间复杂度就是O(1),插入时间复杂度就 大概率的趋向于O(logn(N))。 定时器本身就是从头部开始取数据,跳表这一数据结构就特别匹配定时器的实现。
文件skiplist.h
#ifndef _MARK_SKIPLIST_
#define _MARK_SKIPLIST_
#define ZSKIPLIST_MAXLEVEL 32
#define ZSKIPLIST_P 0.25
typedef struct zskiplistNode zskiplistNode;
typedef void ( * handler_pt) ( zskiplistNode * node) ;
struct zskiplistNode {
unsigned long score;
handler_pt handler;
struct zskiplistLevel {
struct zskiplistNode * forward;
} level[ ] ;
} ;
typedef struct zskiplist {
struct zskiplistNode * header;
int length;
int level;
} zskiplist;
zskiplist * zslCreate ( void ) ;
void zslFree ( zskiplist * zsl) ;
zskiplistNode * zslInsert ( zskiplist * zsl, unsigned long score, handler_pt func) ;
zskiplistNode* zslMin ( zskiplist * zsl) ;
void zslDeleteHead ( zskiplist * zsl) ;
void zslDelete ( zskiplist * zsl, zskiplistNode* zn) ;
void zslPrint ( zskiplist * zsl) ;
#endif
文件skiplist.c
#include <stdlib.h>
#include <stdio.h>
#include "skiplist.h"
void defaultHandler ( zskiplistNode * node) {
}
zskiplistNode * zslCreateNode ( int level, unsigned long score, handler_pt func) {
zskiplistNode * zn =
malloc ( sizeof ( * zn) + level* sizeof ( struct zskiplistLevel) ) ;
zn-> score = score;
zn-> handler = func;
return zn;
}
zskiplist * zslCreate ( void ) {
int j;
zskiplist * zsl;
zsl = malloc ( sizeof ( * zsl) ) ;
zsl-> level = 1 ;
zsl-> length = 0 ;
zsl-> header = zslCreateNode ( ZSKIPLIST_MAXLEVEL, 0 , defaultHandler) ;
for ( j = 0 ; j < ZSKIPLIST_MAXLEVEL; j++ ) {
zsl-> header-> level[ j] . forward = NULL ;
}
return zsl;
}
void zslFree ( zskiplist * zsl) {
zskiplistNode * node = zsl-> header-> level[ 0 ] . forward, * next;
free ( zsl-> header) ;
while ( node) {
next = node-> level[ 0 ] . forward;
free ( node) ;
node = next;
}
free ( zsl) ;
}
int zslRandomLevel ( void ) {
int level = 1 ;
while ( ( arc4random ( ) & 0xFFFF ) < ( ZSKIPLIST_P * 0xFFFF ) )
level + = 1 ;
return ( level< ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
zskiplistNode * zslInsert ( zskiplist * zsl, unsigned long score, handler_pt fun) {
zskiplistNode * update[ ZSKIPLIST_MAXLEVEL] , * x;
int i, level;
x = zsl-> header;
for ( i = zsl-> level- 1 ; i >= 0 ; i-- ) {
while ( x-> level[ i] . forward &&
x-> level[ i] . forward-> score < score)
{
x = x-> level[ i] . forward;
}
update[ i] = x;
}
level = zslRandomLevel ( ) ;
printf ( "zskiplist add node level = %d\n" , level) ;
if ( level > zsl-> level) {
for ( i = zsl-> level; i < level; i++ ) {
update[ i] = zsl-> header;
}
zsl-> level = level;
}
x = zslCreateNode ( level, score, func) ;
for ( i = 0 ; i < level; i++ ) {
x-> level[ i] . forward = update[ i] -> level[ i] . forward;
update[ i] -> level[ i] . forward = x;
}
zsl-> length++ ;
return x;
}
zskiplistNode* zslMin ( zskiplist * zsl) {
zskiplistNode * x;
x = zsl-> header;
return x-> level[ 0 ] . forward;
}
void zslDeleteHead ( zskiplist * zsl) {
zskiplistNode * update[ ZSKIPLIST_MAXLEVEL] ;
zskiplistNode * x = zslMin ( zsl) ;
if ( ! x) return ;
int i;
for ( i = zsl-> level- 1 ; i >= 0 ; i-- ) {
if ( zsl-> header-> level[ i] . forward == x) {
zsl-> header-> level[ i] . forward = x-> level[ i] . forward;
}
}
while ( zsl-> level > 1 && zsl-> header-> level[ zsl-> level- 1 ] . forward == NULL )
zsl-> level-- ;
zsl-> length-- ;
}
void zslDeleteNode ( zskiplist * zsl, zskiplistNode * x, zskiplistNode * * update) {
int i;
for ( i = 0 ; i < zsl-> level; i++ ) {
if ( update[ i] -> level[ i] . forward == x) {
update[ i] -> level[ i] . forward = x-> level[ i] . forward;
}
}
while ( zsl-> level > 1 && zsl-> header-> level[ zsl-> level- 1 ] . forward == NULL )
zsl-> level-- ;
zsl-> length-- ;
}
void zslDelete ( zskiplist * zsl, zskiplistNode* zn) {
zskiplistNode * update[ ZSKIPLIST_MAXLEVEL] , * x;
int i;
x = zsl-> header;
for ( i = zsl-> level- 1 ; i >= 0 ; i-- ) {
while ( x-> level[ i] . forward &&
x-> level[ i] . forward-> score < zn-> score)
{
x = x-> level[ i] . forward;
}
update[ i] = x;
}
x = x-> level[ 0 ] . forward;
if ( x && zn-> score == x-> score) {
zslDeleteNode ( zsl, x, update) ;
free ( x) ;
}
}
void zslPrint ( zskiplist * zsl) {
zskiplistNode * x;
x = zsl-> header;
x = x-> level[ 0 ] . forward;
printf ( "start print skiplist level = %d\n" , zsl-> level) ;
int i;
for ( i = 0 ; i < zsl-> length; i++ ) {
printf ( "skiplist ele %d: score = %lu\n" , i+ 1 , x-> score) ;
x = x-> level[ 0 ] . forward;
}
}
定时器实现
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <stddef.h>
#include <time.h>
#if defined(__APPLE__)
#include <AvailabilityMacros.h>
#include <sys/time.h>
#include <mach/task.h>
#include <mach/mach.h>
#endif
#include "skiplist.h"
static uint32_t
current_time ( ) {
uint32_t t;
#if !defined(__APPLE__) || defined(AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER)
struct timespec ti;
clock_gettime ( CLOCK_MONOTONIC, & ti) ;
t = ( uint32_t) ti. tv_sec * 1000 ;
t + = ti. tv_nsec / 1000000 ;
#else
struct timeval tv;
gettimeofday ( & tv, NULL ) ;
t = ( uint32_t) tv. tv_sec * 1000 ;
t + = tv. tv_usec / 1000 ;
#endif
return t;
}
zskiplist * init_timer ( ) {
return zslCreate ( ) ;
}
zskiplistNode * add_timer ( zskiplist * zsl, uint32_t msec, handler_pt func) {
msec + = current_time ( ) ;
printf ( "add_timer expire at msec = %u\n" , msec) ;
return zslInsert ( zsl, msec, func) ;
}
void del_timer ( zskiplist * zsl, zskiplistNode * zn) {
zslDelete ( zsl, zn) ;
}
void expire_timer ( zskiplist * zsl) {
zskiplistNode * x;
uint32_t now = current_time ( ) ;
for ( ; ; ) {
x = zslMin ( zsl) ;
if ( ! x) break ;
if ( x-> score > now) break ;
printf ( "touch timer expire time=%lu, now = %u\n" , x-> score, now) ;
x-> handler ( x) ;
zslDeleteHead ( zsl) ;
}
}
void print_hello ( zskiplistNode * zn) {
printf ( "hello world time = %lu\n" , zn-> score) ;
}
int main ( )
{
zskiplist * zsl = init_timer ( ) ;
add_timer ( zsl, 3010 , print_hello) ;
add_timer ( zsl, 3004 , print_hello) ;
zskiplistNode * zn = add_timer ( zsl, 3005 , print_hello) ;
del_timer ( zsl, zn) ;
add_timer ( zsl, 3008 , print_hello) ;
add_timer ( zsl, 3003 , print_hello) ;
for ( ; ; ) {
expire_timer ( zsl) ;
usleep ( 10000 ) ;
}
return 0 ;
}