⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vector.c

📁 pptp第二层隧道模块
💻 C
字号:
/* vector.c ..... store a vector of PPTP_CALL information and search it *                efficiently. *                C. Scott Ananian <cananian@alumni.princeton.edu> * * $Id: vector.c,v 1.3 2003/06/17 10:12:55 reink Exp $ */#include <stdlib.h>#include <string.h>#include <assert.h>#include "pptp_ctrl.h"#include "vector.h"/* #define VECTOR_DEBUG */#ifndef TRUE#define TRUE 1#endif#ifndef FALSE#define FALSE 0#endifstruct vector_item {    int key;    PPTP_CALL *call;};struct vector_struct {    struct vector_item *item;    int size;    int alloc;#ifdef VECTOR_DEBUG    int key_max;#endif};static struct vector_item *binary_search(VECTOR *v, int key);/*** vector_create ************************************************************/VECTOR *vector_create(){    const int INITIAL_SIZE = 4;    VECTOR *v = malloc(sizeof(*v));    if (v == NULL) return v;    v->size = 0;    v->alloc = INITIAL_SIZE;    v->item = malloc(sizeof(*(v->item)) * (v->alloc));#ifdef VECTOR_DEBUG    v->key_max = -1;#endif    if (v->item == NULL) { free(v); return NULL; }    else return v;}/*** vector_destroy ***********************************************************/void vector_destroy(VECTOR *v){    free(v->item);#ifdef VECTOR_DEBUG    v->item = NULL;#endif    free(v);}/*** vector_size **************************************************************/int vector_size(VECTOR *v){    assert(v != NULL);    return v->size;}/*** vector_insert************************************************************* * nice thing about file descriptors is that we are assured by POSIX  * that they are monotonically increasing. */int vector_insert(VECTOR *v, int key, PPTP_CALL * call){    int i;    assert(v != NULL && call != NULL);    assert(!vector_contains(v, key));#ifdef VECTOR_DEBUG    assert(v->key_max < key);#endif    if (!(v->size < v->alloc)) {        void *tmp = realloc(v->item, sizeof(*(v->item)) * 2 * v->alloc);        if (tmp != NULL) {            v->alloc *= 2;            v->item = tmp;        } else return FALSE; /* failed to alloc memory. */    }    assert(v->size < v->alloc);    /* for safety, we make this work in the general case;     * but this is optimized for adding call to the end of the vector.     */    for(i = v->size - 1; i >= 0; i--)        if (v->item[i].key < key)            break;    /* insert after item i */    memmove(&v->item[i + 2], &v->item[i + 1],            (v->size - i - 1) * sizeof(*(v->item)));    v->item[i + 1].key  = key;    v->item[i + 1].call = call;    v->size++;#ifdef VECTOR_DEBUG    if (v->key_max < key) /* ie, always. */        v->key_max = key;#endif    return TRUE;}/*** vector_remove ************************************************************/int  vector_remove(VECTOR *v, int key){    struct vector_item *tmp;    assert(v != NULL);    if ((tmp =binary_search(v,key)) == NULL) return FALSE;    assert(tmp >= v->item && tmp < v->item + v->size);    memmove(tmp, tmp + 1, (v->size - (v->item - tmp) - 1) * sizeof(*(v->item)));    v->size--;    return TRUE;}/*** vector_search ************************************************************/int  vector_search(VECTOR *v, int key, PPTP_CALL **call){    struct vector_item *tmp;    assert(v != NULL);    tmp = binary_search(v, key);    if (tmp ==NULL) return FALSE;    *call = tmp->call;    return TRUE;}/*** vector_contains **********************************************************/int  vector_contains(VECTOR *v, int key){    assert(v != NULL);    return (binary_search(v, key) != NULL);}/*** vector_item **************************************************************/static struct vector_item *binary_search(VECTOR *v, int key){    int l,r,x;    l = 0;    r = v->size - 1;    while (r >= l) {        x = (l + r)/2;        if (key <  v->item[x].key) r = x - 1; else l = x + 1;        if (key == v->item[x].key) return &(v->item[x]);    }    return NULL;}/*** vector_scan *************************************************************** * Hmm.  Let's be fancy and use a binary search for the first * unused key, taking advantage of the list is stored sorted; ie * we can look at pointers and keys at two different locations,  * and if (ptr1 - ptr2) = (key1 - key2) then all the slots * between ptr1 and ptr2 are filled.  Note that ptr1-ptr2 should * never be greater than key1-key2 (no duplicate keys!)... we * check for this. */int vector_scan(VECTOR *v, int lo, int hi, int *key){    int l,r,x;    assert(v != NULL);    assert(key != NULL);    if ((v->size<1) || (lo < v->item[0].key)) { *key = lo; return TRUE; }    /* our array bounds */    l = 0;  r = v->size - 1;    while (r > l) {        /* check for a free spot right after l */        if (v->item[l].key + 1 < v->item[l + 1].key) { /* found it! */            *key = v->item[l].key + 1;            return TRUE;        }        /* no dice. Let's see if the free spot is before or after the midpoint */        x = (l + r)/2;        /* Okay, we have right (r), left (l) and the probe (x). */        assert(x - l <= v->item[x].key - v->item[l].key);        assert(r - x <= v->item[r].key - v->item[x].key);        if (x - l < v->item[x].key - v->item[l].key)            /* room between l and x */            r = x;        else /* no room between l and x */            if (r - x < v->item[r].key - v->item[x].key)                /* room between x and r */                l = x;            else /* no room between x and r, either */                break; /* game over, man. */    }    /* no room found in already allocated space.  Check to see if     * there's free space above allocated entries. */    if (v->item[v->size - 1].key < hi) {        *key = v->item[v->size - 1].key + 1;        return TRUE;    }    /* outta luck */    return FALSE;}/*** vector_get_Nth ***********************************************************/PPTP_CALL * vector_get_Nth(VECTOR *v, int n){    assert(v != NULL);    assert(0 <= n && n < vector_size(v));    return v->item[n].call;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -