17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate 23*032624d5Sbasabi /* 24*032624d5Sbasabi * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25*032624d5Sbasabi * Use is subject to license terms. 26*032624d5Sbasabi */ 27*032624d5Sbasabi 287c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 297c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate 33*032624d5Sbasabi #pragma ident "%Z%%M% %I% %E% SMI" 347c478bd9Sstevel@tonic-gate /************************************************************************** 357c478bd9Sstevel@tonic-gate *** General-Purpose Event List Manager *** 367c478bd9Sstevel@tonic-gate ************************************************************************** 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate description: These routines maintain a time-ordered list of events. 397c478bd9Sstevel@tonic-gate functions available: 407c478bd9Sstevel@tonic-gate init : Creates and initializes the data structure. 417c478bd9Sstevel@tonic-gate See the reference for parameters to init. 427c478bd9Sstevel@tonic-gate add(&event,time,id) : Adds an event to the list. 437c478bd9Sstevel@tonic-gate remove(id) : Removes events (with appropriate id). 447c478bd9Sstevel@tonic-gate empty : Returns true if the list is empty, false otherwise. 457c478bd9Sstevel@tonic-gate first : Removes the element at the head of the list. 467c478bd9Sstevel@tonic-gate Returns a pointer to the event. 477c478bd9Sstevel@tonic-gate delete : Frees up all allocated storage associated 487c478bd9Sstevel@tonic-gate with the event list. 497c478bd9Sstevel@tonic-gate reference: Franta, W. R. and Maly, K., 507c478bd9Sstevel@tonic-gate "An efficient data structure for the 517c478bd9Sstevel@tonic-gate simulation event set ", CACM Vol. 20(8), 527c478bd9Sstevel@tonic-gate Aug 1977, pp. 596-602. 537c478bd9Sstevel@tonic-gate machine dependant: the constant INFINITY 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate *************************************************************************/ 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate #include <sys/types.h> 597c478bd9Sstevel@tonic-gate #include <stdlib.h> 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate extern void *xmalloc(size_t); 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate #define INFINITY 2147483647L /* upper bound on time */ 647c478bd9Sstevel@tonic-gate #define NULL 0 /* a null pointer */ 657c478bd9Sstevel@tonic-gate #define TRUE 1 667c478bd9Sstevel@tonic-gate #define FALSE 0 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* the following parameters are set in init */ 697c478bd9Sstevel@tonic-gate static int DU; /* number of time intervals */ 707c478bd9Sstevel@tonic-gate static time_t LB; /* lower bound on time */ 717c478bd9Sstevel@tonic-gate static time_t DT; /* width of interval */ 727c478bd9Sstevel@tonic-gate static int NLIM; /* max notices per sublist */ 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate /* a notice points to an event. a notice has the following fields: 757c478bd9Sstevel@tonic-gate time = time of the event. 767c478bd9Sstevel@tonic-gate id = identifier for an event or class of events that may need 777c478bd9Sstevel@tonic-gate to be removed (other than at the front of the list). 787c478bd9Sstevel@tonic-gate event = pointer to the event. 797c478bd9Sstevel@tonic-gate isdummy = tells whether this notice points to a real event or 807c478bd9Sstevel@tonic-gate is just a dummy notice (one that is used to "mark off" 817c478bd9Sstevel@tonic-gate the time intervals that the user specifies in init). 827c478bd9Sstevel@tonic-gate key = points back to the key that points to this notice, 837c478bd9Sstevel@tonic-gate if there is one. 847c478bd9Sstevel@tonic-gate left = points to the notice immediately preceding this one. 857c478bd9Sstevel@tonic-gate right = points to the notice immediately following this one. */ 867c478bd9Sstevel@tonic-gate struct notice { time_t time; 877c478bd9Sstevel@tonic-gate int id; 887c478bd9Sstevel@tonic-gate void *event; 897c478bd9Sstevel@tonic-gate short int isdummy; 907c478bd9Sstevel@tonic-gate struct key *key; 917c478bd9Sstevel@tonic-gate struct notice *left; 927c478bd9Sstevel@tonic-gate struct notice *right; }; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate /* current points to the front of the list of notices (events) */ 957c478bd9Sstevel@tonic-gate struct notice *current=NULL; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate /* a key points to a sublist of notices. a key has the following fields: 987c478bd9Sstevel@tonic-gate time = max time of notices in sublist. 997c478bd9Sstevel@tonic-gate numnote = number of notices in sublist. 1007c478bd9Sstevel@tonic-gate notice = pointer to the notice with max time. 1017c478bd9Sstevel@tonic-gate left = points to the key immediately preceding this one. 1027c478bd9Sstevel@tonic-gate right = points to the key immediately following this one. */ 1037c478bd9Sstevel@tonic-gate struct key { time_t time; 1047c478bd9Sstevel@tonic-gate int numnote; 1057c478bd9Sstevel@tonic-gate struct notice *notice; 1067c478bd9Sstevel@tonic-gate struct key *left; 1077c478bd9Sstevel@tonic-gate struct key *right; }; 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate /* the index list breaks the keys into time intervals as specified in init. 1107c478bd9Sstevel@tonic-gate the index is "shifted" one time interval whenever el_first returns an 1117c478bd9Sstevel@tonic-gate event with a time greater than the max time of the first interval 1127c478bd9Sstevel@tonic-gate (eg. with intervals of a day which span one week (MTWTFSS), 1137c478bd9Sstevel@tonic-gate if el_first finds the next event is on tuesday, then 1147c478bd9Sstevel@tonic-gate the intervals of the event list get shifted (TWTFSSM). */ 1157c478bd9Sstevel@tonic-gate struct index { struct key *key; 1167c478bd9Sstevel@tonic-gate struct index *right; }; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate static struct index *index=NULL; /* index pts to the front of the index list */ 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate /***********************/ 1217c478bd9Sstevel@tonic-gate void 1227c478bd9Sstevel@tonic-gate el_init(du,lb,dt,nlim) 1237c478bd9Sstevel@tonic-gate /***********************/ 1247c478bd9Sstevel@tonic-gate int du, nlim; 1257c478bd9Sstevel@tonic-gate time_t lb, dt; 1267c478bd9Sstevel@tonic-gate { 1277c478bd9Sstevel@tonic-gate int i; 1287c478bd9Sstevel@tonic-gate time_t t; 1297c478bd9Sstevel@tonic-gate struct index *indprev,*ind; 1307c478bd9Sstevel@tonic-gate struct key *kprev, *k; 1317c478bd9Sstevel@tonic-gate struct notice *nprev, *n; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate if ((du<1) || (dt<1) || (nlim<1)) return; 1347c478bd9Sstevel@tonic-gate DU = du + 1; 1357c478bd9Sstevel@tonic-gate LB = lb; 1367c478bd9Sstevel@tonic-gate DT = dt; 1377c478bd9Sstevel@tonic-gate NLIM = nlim; 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate /* 1407c478bd9Sstevel@tonic-gate * initialize index, keys, and notices 1417c478bd9Sstevel@tonic-gate */ 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate /* create first dummy notice */ 1447c478bd9Sstevel@tonic-gate n= (struct notice *) xmalloc(sizeof(struct notice)); 1457c478bd9Sstevel@tonic-gate n->time = LB; 1467c478bd9Sstevel@tonic-gate n->isdummy = TRUE; 1477c478bd9Sstevel@tonic-gate n->left = NULL; 1487c478bd9Sstevel@tonic-gate nprev = n; 1497c478bd9Sstevel@tonic-gate /* create first dummy key */ 1507c478bd9Sstevel@tonic-gate k= (struct key *) xmalloc(sizeof(struct key)); 1517c478bd9Sstevel@tonic-gate k->time = LB; 1527c478bd9Sstevel@tonic-gate k->numnote = 1; 1537c478bd9Sstevel@tonic-gate k->notice = n; 1547c478bd9Sstevel@tonic-gate k->left = NULL; 1557c478bd9Sstevel@tonic-gate kprev = k; 1567c478bd9Sstevel@tonic-gate /* make notice point to key */ 1577c478bd9Sstevel@tonic-gate n->key = k; 1587c478bd9Sstevel@tonic-gate /* no index element to allocate this time */ 1597c478bd9Sstevel@tonic-gate indprev = NULL; 1607c478bd9Sstevel@tonic-gate /* create dummy notices, dummy keys, and index elements */ 1617c478bd9Sstevel@tonic-gate t = LB; 1627c478bd9Sstevel@tonic-gate for (i=1; i<DU; i++) { 1637c478bd9Sstevel@tonic-gate t = t + DT; 1647c478bd9Sstevel@tonic-gate n = (struct notice *) xmalloc(sizeof(struct notice)); 1657c478bd9Sstevel@tonic-gate n->time = t; 1667c478bd9Sstevel@tonic-gate n->isdummy = TRUE; 1677c478bd9Sstevel@tonic-gate n->left = nprev; 1687c478bd9Sstevel@tonic-gate nprev->right = n; 1697c478bd9Sstevel@tonic-gate nprev = n; 1707c478bd9Sstevel@tonic-gate k = (struct key *) xmalloc(sizeof(struct key)); 1717c478bd9Sstevel@tonic-gate k->time = t; 1727c478bd9Sstevel@tonic-gate k->numnote = 1; 1737c478bd9Sstevel@tonic-gate k->notice = n; 1747c478bd9Sstevel@tonic-gate k->left = kprev; 1757c478bd9Sstevel@tonic-gate kprev->right = k; 1767c478bd9Sstevel@tonic-gate kprev = k; 1777c478bd9Sstevel@tonic-gate n->key = k; 1787c478bd9Sstevel@tonic-gate ind = (struct index *) xmalloc(sizeof(struct index)); 1797c478bd9Sstevel@tonic-gate ind->key = k; 1807c478bd9Sstevel@tonic-gate if (indprev == NULL) index = ind; 1817c478bd9Sstevel@tonic-gate else indprev->right = ind; 1827c478bd9Sstevel@tonic-gate indprev = ind; } 1837c478bd9Sstevel@tonic-gate /* create last dummy notice */ 1847c478bd9Sstevel@tonic-gate n = (struct notice *) xmalloc(sizeof(struct notice)); 1857c478bd9Sstevel@tonic-gate n->time = INFINITY; 1867c478bd9Sstevel@tonic-gate n->isdummy = TRUE; 1877c478bd9Sstevel@tonic-gate n->left = nprev; 1887c478bd9Sstevel@tonic-gate n->right = NULL; 1897c478bd9Sstevel@tonic-gate nprev->right = n; 1907c478bd9Sstevel@tonic-gate /* create last dummy key */ 1917c478bd9Sstevel@tonic-gate k = (struct key *) xmalloc(sizeof(struct key)); 1927c478bd9Sstevel@tonic-gate k->time = INFINITY; 1937c478bd9Sstevel@tonic-gate k->numnote = 1; 1947c478bd9Sstevel@tonic-gate k->notice = n; 1957c478bd9Sstevel@tonic-gate k->left = kprev; 1967c478bd9Sstevel@tonic-gate k->right = NULL; 1977c478bd9Sstevel@tonic-gate kprev->right = k; 1987c478bd9Sstevel@tonic-gate n->key = k; 1997c478bd9Sstevel@tonic-gate /* create last index element */ 2007c478bd9Sstevel@tonic-gate ind = (struct index *) xmalloc(sizeof(struct index)); 2017c478bd9Sstevel@tonic-gate ind->key = k; 2027c478bd9Sstevel@tonic-gate ind->right = NULL; 2037c478bd9Sstevel@tonic-gate indprev->right = ind; 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate current = NULL; 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate /**************************/ 2107c478bd9Sstevel@tonic-gate void 2117c478bd9Sstevel@tonic-gate el_add(event,time,id) 2127c478bd9Sstevel@tonic-gate /**************************/ 2137c478bd9Sstevel@tonic-gate void *event; 2147c478bd9Sstevel@tonic-gate int id; 2157c478bd9Sstevel@tonic-gate time_t time; 2167c478bd9Sstevel@tonic-gate { 2177c478bd9Sstevel@tonic-gate /* add works slightly differently than in the reference. if the 2187c478bd9Sstevel@tonic-gate sublist to be inserted into is full (numnote = NLIM), 2197c478bd9Sstevel@tonic-gate the sublist is split in half. thus the size of the sublists 2207c478bd9Sstevel@tonic-gate in this implementation normally ranges from NLIM/2 to NLIM. */ 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate struct index *ind; 2237c478bd9Sstevel@tonic-gate struct key *k,*k2; 2247c478bd9Sstevel@tonic-gate struct notice *n,*n2; 2257c478bd9Sstevel@tonic-gate int i; 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate if ((index==NULL) || (time<LB)) return; 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate /* allocate new notice */ 2307c478bd9Sstevel@tonic-gate n = (struct notice *) xmalloc(sizeof(struct notice)); 2317c478bd9Sstevel@tonic-gate n->time = time; 2327c478bd9Sstevel@tonic-gate n->id = id; 2337c478bd9Sstevel@tonic-gate n->event = event; 2347c478bd9Sstevel@tonic-gate n->isdummy = FALSE; 2357c478bd9Sstevel@tonic-gate n->key = NULL; 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate /* find the right interval */ 2387c478bd9Sstevel@tonic-gate ind = index; 2397c478bd9Sstevel@tonic-gate while ((ind->key)->time <= time) ind = ind->right; 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate /* find the right key */ 2427c478bd9Sstevel@tonic-gate k = (ind->key)->left; 2437c478bd9Sstevel@tonic-gate while (k->time > time) k = k->left; 2447c478bd9Sstevel@tonic-gate k = k->right; 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate /* (k->time>time) and ((k->left)->time<=time) */ 2477c478bd9Sstevel@tonic-gate if (k->numnote == NLIM) { 2487c478bd9Sstevel@tonic-gate /* k's sublist is full, so split it */ 2497c478bd9Sstevel@tonic-gate k->numnote = NLIM / 2; 2507c478bd9Sstevel@tonic-gate n2 = k->notice; 2517c478bd9Sstevel@tonic-gate for (i=1; i<=NLIM/2; i++) n2 = n2->left; 2527c478bd9Sstevel@tonic-gate /* create a key which will point to notice n2 */ 2537c478bd9Sstevel@tonic-gate k2 = (struct key *) xmalloc(sizeof(struct key)); 2547c478bd9Sstevel@tonic-gate k2->time = n2->time; 2557c478bd9Sstevel@tonic-gate k2->numnote = NLIM - NLIM/2; 2567c478bd9Sstevel@tonic-gate k2->notice = n2; 2577c478bd9Sstevel@tonic-gate k2->right = k; 2587c478bd9Sstevel@tonic-gate k2->left = k->left; 2597c478bd9Sstevel@tonic-gate k->left = k2; 2607c478bd9Sstevel@tonic-gate (k2->left)->right = k2; 2617c478bd9Sstevel@tonic-gate n2->key = k2; /* have n2 point back to k2 */ 2627c478bd9Sstevel@tonic-gate /* which of the new sublists will hold the new notice? */ 2637c478bd9Sstevel@tonic-gate if (k2->time > time) k = k2; } 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate /* the new notice n is ready to be inserted 2667c478bd9Sstevel@tonic-gate k points to the appropriate sublist */ 2677c478bd9Sstevel@tonic-gate k->numnote = k->numnote + 1; 2687c478bd9Sstevel@tonic-gate n2 = k->notice; 2697c478bd9Sstevel@tonic-gate while (n2->time > time) n2 = n2->left; 2707c478bd9Sstevel@tonic-gate n->right = n2->right; 2717c478bd9Sstevel@tonic-gate n->left = n2; 2727c478bd9Sstevel@tonic-gate (n2->right)->left = n; 2737c478bd9Sstevel@tonic-gate n2->right = n; 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate if ( (current == NULL) || (current->time > time) ) current = n; 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate /************************/ 2807c478bd9Sstevel@tonic-gate void 2817c478bd9Sstevel@tonic-gate el_remove(id,flag) 2827c478bd9Sstevel@tonic-gate /************************/ 2837c478bd9Sstevel@tonic-gate int id,flag; 2847c478bd9Sstevel@tonic-gate { 2857c478bd9Sstevel@tonic-gate /* remove finds notices n that need to be removed by traversing thru 2867c478bd9Sstevel@tonic-gate the notice list. if n is the sole element of a sublist, the 2877c478bd9Sstevel@tonic-gate sublist is deleted. if not, an adjacent sublist is merged with 2887c478bd9Sstevel@tonic-gate n's sublist, if that is possible. after these checks, n is removed. */ 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate struct notice *n,*n2; 2917c478bd9Sstevel@tonic-gate struct key *k,*kl,*kr; 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate if ((index==NULL) || (current==NULL)) return; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate n = current; 2967c478bd9Sstevel@tonic-gate while ( n != NULL) { 2977c478bd9Sstevel@tonic-gate while ( (n!=NULL) && ((n->isdummy)||(n->id!=id)) ) n = n->right; 2987c478bd9Sstevel@tonic-gate if (n != NULL) { 2997c478bd9Sstevel@tonic-gate /* n should be deleted */ 3007c478bd9Sstevel@tonic-gate if ( (n->key!=NULL) && ((n->key)->numnote==1) ) { 3017c478bd9Sstevel@tonic-gate /* n = sole element of a sublist */ 3027c478bd9Sstevel@tonic-gate k = n->key; 3037c478bd9Sstevel@tonic-gate (k->left)->right = k->right; 3047c478bd9Sstevel@tonic-gate (k->right)->left = k->left; 3057c478bd9Sstevel@tonic-gate free(k); } 3067c478bd9Sstevel@tonic-gate else { if (n->key != NULL) { 3077c478bd9Sstevel@tonic-gate /* n has a key pointing to it */ 3087c478bd9Sstevel@tonic-gate (n->left)->key = n->key; 3097c478bd9Sstevel@tonic-gate (n->key)->time = (n->left)->time; 3107c478bd9Sstevel@tonic-gate (n->key)->notice = n->left; } 3117c478bd9Sstevel@tonic-gate /* find the key that points to this sublist */ 3127c478bd9Sstevel@tonic-gate n2 = n; 3137c478bd9Sstevel@tonic-gate while (n2->key == NULL) n2 = n2->right; 3147c478bd9Sstevel@tonic-gate k = n2->key; 3157c478bd9Sstevel@tonic-gate k->numnote = k->numnote - 1; 3167c478bd9Sstevel@tonic-gate /* check if two adjacent sublists can be merged 3177c478bd9Sstevel@tonic-gate first check left, then check right */ 3187c478bd9Sstevel@tonic-gate kl = k->left; 3197c478bd9Sstevel@tonic-gate kr = k->right; 3207c478bd9Sstevel@tonic-gate if ( (!(kl->notice)->isdummy) && 3217c478bd9Sstevel@tonic-gate ((kl->numnote+k->numnote)<=NLIM) ) { 3227c478bd9Sstevel@tonic-gate /* delete the key to the left */ 3237c478bd9Sstevel@tonic-gate (kl->notice)->key = NULL; 3247c478bd9Sstevel@tonic-gate k->numnote += kl->numnote; 3257c478bd9Sstevel@tonic-gate (kl->left)->right = k; 3267c478bd9Sstevel@tonic-gate k->left = kl->left; 3277c478bd9Sstevel@tonic-gate free(kl); } 3287c478bd9Sstevel@tonic-gate else if ( (!(k->notice)->isdummy) && 3297c478bd9Sstevel@tonic-gate ((kr->numnote+k->numnote)<=NLIM) ) { 3307c478bd9Sstevel@tonic-gate /* delete this key */ 3317c478bd9Sstevel@tonic-gate (k->notice)->key = NULL; 3327c478bd9Sstevel@tonic-gate kr->numnote += k->numnote; 3337c478bd9Sstevel@tonic-gate (k->left)->right = kr; 3347c478bd9Sstevel@tonic-gate kr->left = k->left; 3357c478bd9Sstevel@tonic-gate free(k); } 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate /* delete n, then advance n down the list */ 3387c478bd9Sstevel@tonic-gate (n->left)->right = n->right; 3397c478bd9Sstevel@tonic-gate (n->right)->left = n->left; 3407c478bd9Sstevel@tonic-gate n2 = n->right; 3417c478bd9Sstevel@tonic-gate free(n); 3427c478bd9Sstevel@tonic-gate n = n2; 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate if (flag) break; 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate /* now reset current */ 3477c478bd9Sstevel@tonic-gate k = (index->key)->left; 3487c478bd9Sstevel@tonic-gate while (k->left != NULL) k = k->left; 3497c478bd9Sstevel@tonic-gate n = (k->notice)->right; 3507c478bd9Sstevel@tonic-gate while ((n!=NULL) && (n->isdummy)) n = n->right; 3517c478bd9Sstevel@tonic-gate current = n; 3527c478bd9Sstevel@tonic-gate } 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate /*************************/ 356*032624d5Sbasabi int 357*032624d5Sbasabi el_empty(void) 3587c478bd9Sstevel@tonic-gate /*************************/ 3597c478bd9Sstevel@tonic-gate { 3607c478bd9Sstevel@tonic-gate if (current == NULL) return(1); 3617c478bd9Sstevel@tonic-gate else return(0); 3627c478bd9Sstevel@tonic-gate } 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate /*************************/ 3667c478bd9Sstevel@tonic-gate void * 367*032624d5Sbasabi el_first(void) 3687c478bd9Sstevel@tonic-gate /*************************/ 3697c478bd9Sstevel@tonic-gate { 3707c478bd9Sstevel@tonic-gate struct notice *n,*fn; 3717c478bd9Sstevel@tonic-gate struct key *k,*fk; 3727c478bd9Sstevel@tonic-gate struct index *ind,*fi; 3737c478bd9Sstevel@tonic-gate int ctr,*val; 3747c478bd9Sstevel@tonic-gate time_t next_int; 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate if ((index==NULL) || (current==NULL)) return(NULL); 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate while ((index->key)->time < current->time) { 3797c478bd9Sstevel@tonic-gate if (DU == 2) { 3807c478bd9Sstevel@tonic-gate /* only two intervals, so relabel first one */ 3817c478bd9Sstevel@tonic-gate k = index->key; 3827c478bd9Sstevel@tonic-gate k->time += DT; 3837c478bd9Sstevel@tonic-gate (k->notice)->time += DT; 3847c478bd9Sstevel@tonic-gate continue; } 3857c478bd9Sstevel@tonic-gate /* remove the notice, key, and index corresponding 3867c478bd9Sstevel@tonic-gate to the first time interval. Then split the 3877c478bd9Sstevel@tonic-gate overflow interval into a normal interval 3887c478bd9Sstevel@tonic-gate plus an overflow interval. */ 3897c478bd9Sstevel@tonic-gate fi = index; 3907c478bd9Sstevel@tonic-gate fk = fi->key; 3917c478bd9Sstevel@tonic-gate fn = fk->notice; 3927c478bd9Sstevel@tonic-gate (fn->left)->right = fn->right; 3937c478bd9Sstevel@tonic-gate (fn->right)->left = fn->left; 3947c478bd9Sstevel@tonic-gate (fk->left)->right = fk->right; 3957c478bd9Sstevel@tonic-gate (fk->right)->left = fk->left; 3967c478bd9Sstevel@tonic-gate index = index->right; 3977c478bd9Sstevel@tonic-gate /* find where to split */ 3987c478bd9Sstevel@tonic-gate ind = index; 3997c478bd9Sstevel@tonic-gate while ((ind->right)->right != NULL) ind = ind->right; 4007c478bd9Sstevel@tonic-gate /* ind points to the next to last index interval */ 4017c478bd9Sstevel@tonic-gate k = ind->key; 4027c478bd9Sstevel@tonic-gate next_int = k->time + DT; /* upper bound on new inter. */ 4037c478bd9Sstevel@tonic-gate while (k->time < next_int) k = k->right; 4047c478bd9Sstevel@tonic-gate /* k points to the appropriate sublist of notices */ 4057c478bd9Sstevel@tonic-gate n = (k->notice)->left; 4067c478bd9Sstevel@tonic-gate ctr = 1; 4077c478bd9Sstevel@tonic-gate while (n->time >= next_int) { 4087c478bd9Sstevel@tonic-gate ctr++; 4097c478bd9Sstevel@tonic-gate n = n->left; } 4107c478bd9Sstevel@tonic-gate n = n->right; 4117c478bd9Sstevel@tonic-gate /* n points to first notice of the new overflow interval 4127c478bd9Sstevel@tonic-gate ctr tells how many notices are in the first sublist 4137c478bd9Sstevel@tonic-gate of the new overflow interval 4147c478bd9Sstevel@tonic-gate insert the new index element */ 4157c478bd9Sstevel@tonic-gate fi->right = ind->right; 4167c478bd9Sstevel@tonic-gate ind->right = fi; 4177c478bd9Sstevel@tonic-gate /* insert the new dummy key */ 4187c478bd9Sstevel@tonic-gate fk->time = next_int; 4197c478bd9Sstevel@tonic-gate fk->numnote = k->numnote - ctr + 1; 4207c478bd9Sstevel@tonic-gate fk->left = k->left; 4217c478bd9Sstevel@tonic-gate fk->right = k; 4227c478bd9Sstevel@tonic-gate (k->left)->right = fk; 4237c478bd9Sstevel@tonic-gate k->left = fk; 4247c478bd9Sstevel@tonic-gate k->numnote = ctr; 4257c478bd9Sstevel@tonic-gate /* insert the new dummy notice */ 4267c478bd9Sstevel@tonic-gate fn->time = next_int; 4277c478bd9Sstevel@tonic-gate fn->left = n->left; 4287c478bd9Sstevel@tonic-gate fn->right = n; 4297c478bd9Sstevel@tonic-gate (n->left)->right = fn; 4307c478bd9Sstevel@tonic-gate n->left = fn; } 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate /* remove the first element of the list */ 4337c478bd9Sstevel@tonic-gate (current->left)->right = current->right; 4347c478bd9Sstevel@tonic-gate (current->right)->left = current->left; 4357c478bd9Sstevel@tonic-gate /* now update the numnote field in the appropriate key */ 4367c478bd9Sstevel@tonic-gate n = current; 4377c478bd9Sstevel@tonic-gate while ( n->key == NULL ) n = n->right; 4387c478bd9Sstevel@tonic-gate k = n->key; 4397c478bd9Sstevel@tonic-gate k->numnote = k->numnote - 1; 4407c478bd9Sstevel@tonic-gate /* if numnote = 0 then this key must be removed */ 4417c478bd9Sstevel@tonic-gate if (k->numnote == 0) { 4427c478bd9Sstevel@tonic-gate (k->left)->right = k->right; 4437c478bd9Sstevel@tonic-gate (k->right)->left = k->left; 4447c478bd9Sstevel@tonic-gate free(k); } 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate /* now set current to be the head of the list */ 4477c478bd9Sstevel@tonic-gate fn = current->right; 4487c478bd9Sstevel@tonic-gate while ( (fn != NULL) && (fn->isdummy) ) 4497c478bd9Sstevel@tonic-gate fn = fn->right; 4507c478bd9Sstevel@tonic-gate val = current->event; 4517c478bd9Sstevel@tonic-gate free(current); 4527c478bd9Sstevel@tonic-gate current = fn; 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate return(val); 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate /******************/ 4597c478bd9Sstevel@tonic-gate void 460*032624d5Sbasabi el_delete(void) 4617c478bd9Sstevel@tonic-gate /******************/ 4627c478bd9Sstevel@tonic-gate { 4637c478bd9Sstevel@tonic-gate /* el_delete frees up all the space associated with the event list */ 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate struct index *ind,*ind2; 4667c478bd9Sstevel@tonic-gate struct key *k,*k2; 4677c478bd9Sstevel@tonic-gate struct notice *n,*n2; 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate if (index==NULL) return; 4707c478bd9Sstevel@tonic-gate ind = index; 4717c478bd9Sstevel@tonic-gate k = ind->key; 4727c478bd9Sstevel@tonic-gate while (k->left != NULL) k = k->left; 4737c478bd9Sstevel@tonic-gate n = k->notice; 4747c478bd9Sstevel@tonic-gate while (n!=NULL) { 4757c478bd9Sstevel@tonic-gate n2 = n->right; 4767c478bd9Sstevel@tonic-gate free(n); 4777c478bd9Sstevel@tonic-gate n = n2; } 4787c478bd9Sstevel@tonic-gate while (k!=NULL) { 4797c478bd9Sstevel@tonic-gate k2 = k->right; 4807c478bd9Sstevel@tonic-gate free(k); 4817c478bd9Sstevel@tonic-gate k = k2; } 4827c478bd9Sstevel@tonic-gate while (ind!=NULL) { 4837c478bd9Sstevel@tonic-gate ind2 = ind->right; 4847c478bd9Sstevel@tonic-gate free(ind); 4857c478bd9Sstevel@tonic-gate ind = ind2; } 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate index = NULL; 4887c478bd9Sstevel@tonic-gate current = NULL; 4897c478bd9Sstevel@tonic-gate } 490