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 5*e2553d68SSerge Dussud * Common Development and Distribution License (the "License"). 6*e2553d68SSerge Dussud * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate 22032624d5Sbasabi /* 23*e2553d68SSerge Dussud * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24032624d5Sbasabi * Use is subject to license terms. 25032624d5Sbasabi */ 26032624d5Sbasabi 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate 32*e2553d68SSerge Dussud /* ********************************************************************** */ 33*e2553d68SSerge Dussud /* * General-Purpose Event List Manager * */ 34*e2553d68SSerge Dussud /* ********************************************************************** */ 35*e2553d68SSerge Dussud /* 36*e2553d68SSerge Dussud * description: These routines maintain a time-ordered list of events. 37*e2553d68SSerge Dussud * functions available: 38*e2553d68SSerge Dussud * init : Creates and initializes the data structure. 39*e2553d68SSerge Dussud * See the reference for parameters to init. 40*e2553d68SSerge Dussud * add(&event, time, id) : Adds an event to the list. 41*e2553d68SSerge Dussud * Returns: 0 if success, 42*e2553d68SSerge Dussud * -2 if event time is lower 43*e2553d68SSerge Dussud * than Lower Bound time LB 44*e2553d68SSerge Dussud * -1 else 45*e2553d68SSerge Dussud * remove(id) : Removes events (with appropriate id). 46*e2553d68SSerge Dussud * empty : Returns true if the list is empty, false otherwise. 47*e2553d68SSerge Dussud * first : Removes the element at the head of the list. 48*e2553d68SSerge Dussud * Returns a pointer to the event. 49*e2553d68SSerge Dussud * delete : Frees up all allocated storage associated 50*e2553d68SSerge Dussud * with the event list. 51*e2553d68SSerge Dussud * reference: Franta, W. R. and Maly, K., 52*e2553d68SSerge Dussud * "An efficient data structure for the 53*e2553d68SSerge Dussud * simulation event set ", CACM Vol. 20(8), 54*e2553d68SSerge Dussud * Aug 1977, pp. 596-602. 55*e2553d68SSerge Dussud * machine dependant: the constant INFINITY 56*e2553d68SSerge Dussud */ 57*e2553d68SSerge Dussud /* ********************************************************************** */ 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate #include <sys/types.h> 617c478bd9Sstevel@tonic-gate #include <stdlib.h> 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate extern void *xmalloc(size_t); 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate #define INFINITY 2147483647L /* upper bound on time */ 667c478bd9Sstevel@tonic-gate #define NULL 0 /* a null pointer */ 677c478bd9Sstevel@tonic-gate #define TRUE 1 687c478bd9Sstevel@tonic-gate #define FALSE 0 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* the following parameters are set in init */ 717c478bd9Sstevel@tonic-gate static int DU; /* number of time intervals */ 727c478bd9Sstevel@tonic-gate static time_t LB; /* lower bound on time */ 737c478bd9Sstevel@tonic-gate static time_t DT; /* width of interval */ 747c478bd9Sstevel@tonic-gate static int NLIM; /* max notices per sublist */ 757c478bd9Sstevel@tonic-gate 76*e2553d68SSerge Dussud /* 77*e2553d68SSerge Dussud * a notice points to an event. a notice has the following fields: 78*e2553d68SSerge Dussud * time = time of the event. 79*e2553d68SSerge Dussud * id = identifier for an event or class of events that may need 80*e2553d68SSerge Dussud * to be removed (other than at the front of the list). 81*e2553d68SSerge Dussud * event = pointer to the event. 82*e2553d68SSerge Dussud * isdummy = tells whether this notice points to a real event or 83*e2553d68SSerge Dussud * is just a dummy notice (one that is used to "mark off" 84*e2553d68SSerge Dussud * the time intervals that the user specifies in init). 85*e2553d68SSerge Dussud * key = points back to the key that points to this notice, 86*e2553d68SSerge Dussud * if there is one. 87*e2553d68SSerge Dussud * left = points to the notice immediately preceding this one. 88*e2553d68SSerge Dussud * right = points to the notice immediately following this one. 89*e2553d68SSerge Dussud */ 907c478bd9Sstevel@tonic-gate struct notice { time_t time; 917c478bd9Sstevel@tonic-gate int id; 927c478bd9Sstevel@tonic-gate void *event; 937c478bd9Sstevel@tonic-gate short int isdummy; 947c478bd9Sstevel@tonic-gate struct key *key; 957c478bd9Sstevel@tonic-gate struct notice *left; 967c478bd9Sstevel@tonic-gate struct notice *right; }; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /* current points to the front of the list of notices (events) */ 997c478bd9Sstevel@tonic-gate struct notice *current = NULL; 1007c478bd9Sstevel@tonic-gate 101*e2553d68SSerge Dussud /* 102*e2553d68SSerge Dussud * a key points to a sublist of notices. a key has the following fields: 103*e2553d68SSerge Dussud * time = max time of notices in sublist. 104*e2553d68SSerge Dussud * numnote = number of notices in sublist. 105*e2553d68SSerge Dussud * notice = pointer to the notice with max time. 106*e2553d68SSerge Dussud * left = points to the key immediately preceding this one. 107*e2553d68SSerge Dussud * right = points to the key immediately following this one. 108*e2553d68SSerge Dussud */ 1097c478bd9Sstevel@tonic-gate struct key { time_t time; 1107c478bd9Sstevel@tonic-gate int numnote; 1117c478bd9Sstevel@tonic-gate struct notice *notice; 1127c478bd9Sstevel@tonic-gate struct key *left; 1137c478bd9Sstevel@tonic-gate struct key *right; }; 1147c478bd9Sstevel@tonic-gate 115*e2553d68SSerge Dussud /* 116*e2553d68SSerge Dussud * the index list breaks the keys into time intervals as specified in init. 117*e2553d68SSerge Dussud * the index is "shifted" one time interval whenever el_first returns an 118*e2553d68SSerge Dussud * event with a time greater than the max time of the first interval 119*e2553d68SSerge Dussud * (eg. with intervals of a day which span one week (MTWTFSS), 120*e2553d68SSerge Dussud * if el_first finds the next event is on tuesday, then 121*e2553d68SSerge Dussud * the intervals of the event list get shifted (TWTFSSM). 122*e2553d68SSerge Dussud */ 1237c478bd9Sstevel@tonic-gate struct index { struct key *key; 1247c478bd9Sstevel@tonic-gate struct index *right; }; 1257c478bd9Sstevel@tonic-gate 126*e2553d68SSerge Dussud /* index pts to the front of the index list */ 127*e2553d68SSerge Dussud static struct index *index = NULL; 1287c478bd9Sstevel@tonic-gate 129*e2553d68SSerge Dussud /* ******************* */ 1307c478bd9Sstevel@tonic-gate void 1317c478bd9Sstevel@tonic-gate el_init(du, lb, dt, nlim) 132*e2553d68SSerge Dussud /* ******************* */ 1337c478bd9Sstevel@tonic-gate int du, nlim; 1347c478bd9Sstevel@tonic-gate time_t lb, dt; 1357c478bd9Sstevel@tonic-gate { 1367c478bd9Sstevel@tonic-gate int i; 1377c478bd9Sstevel@tonic-gate time_t t; 1387c478bd9Sstevel@tonic-gate struct index *indprev, *ind; 1397c478bd9Sstevel@tonic-gate struct key *kprev, *k; 1407c478bd9Sstevel@tonic-gate struct notice *nprev, *n; 1417c478bd9Sstevel@tonic-gate 142*e2553d68SSerge Dussud if ((du < 1) || (dt < 1) || (nlim < 1)) 143*e2553d68SSerge Dussud return; 1447c478bd9Sstevel@tonic-gate DU = du + 1; 1457c478bd9Sstevel@tonic-gate LB = lb; 1467c478bd9Sstevel@tonic-gate DT = dt; 1477c478bd9Sstevel@tonic-gate NLIM = nlim; 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate /* 1507c478bd9Sstevel@tonic-gate * initialize index, keys, and notices 1517c478bd9Sstevel@tonic-gate */ 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate /* create first dummy notice */ 1547c478bd9Sstevel@tonic-gate n = (struct notice *)xmalloc(sizeof (struct notice)); 1557c478bd9Sstevel@tonic-gate n->time = LB; 1567c478bd9Sstevel@tonic-gate n->isdummy = TRUE; 1577c478bd9Sstevel@tonic-gate n->left = NULL; 1587c478bd9Sstevel@tonic-gate nprev = n; 1597c478bd9Sstevel@tonic-gate /* create first dummy key */ 1607c478bd9Sstevel@tonic-gate k = (struct key *)xmalloc(sizeof (struct key)); 1617c478bd9Sstevel@tonic-gate k->time = LB; 1627c478bd9Sstevel@tonic-gate k->numnote = 1; 1637c478bd9Sstevel@tonic-gate k->notice = n; 1647c478bd9Sstevel@tonic-gate k->left = NULL; 1657c478bd9Sstevel@tonic-gate kprev = k; 1667c478bd9Sstevel@tonic-gate /* make notice point to key */ 1677c478bd9Sstevel@tonic-gate n->key = k; 1687c478bd9Sstevel@tonic-gate /* no index element to allocate this time */ 1697c478bd9Sstevel@tonic-gate indprev = NULL; 1707c478bd9Sstevel@tonic-gate /* create dummy notices, dummy keys, and index elements */ 1717c478bd9Sstevel@tonic-gate t = LB; 1727c478bd9Sstevel@tonic-gate for (i = 1; i < DU; i++) { 1737c478bd9Sstevel@tonic-gate t = t + DT; 1747c478bd9Sstevel@tonic-gate n = (struct notice *)xmalloc(sizeof (struct notice)); 1757c478bd9Sstevel@tonic-gate n->time = t; 1767c478bd9Sstevel@tonic-gate n->isdummy = TRUE; 1777c478bd9Sstevel@tonic-gate n->left = nprev; 1787c478bd9Sstevel@tonic-gate nprev->right = n; 1797c478bd9Sstevel@tonic-gate nprev = n; 1807c478bd9Sstevel@tonic-gate k = (struct key *)xmalloc(sizeof (struct key)); 1817c478bd9Sstevel@tonic-gate k->time = t; 1827c478bd9Sstevel@tonic-gate k->numnote = 1; 1837c478bd9Sstevel@tonic-gate k->notice = n; 1847c478bd9Sstevel@tonic-gate k->left = kprev; 1857c478bd9Sstevel@tonic-gate kprev->right = k; 1867c478bd9Sstevel@tonic-gate kprev = k; 1877c478bd9Sstevel@tonic-gate n->key = k; 1887c478bd9Sstevel@tonic-gate ind = (struct index *)xmalloc(sizeof (struct index)); 1897c478bd9Sstevel@tonic-gate ind->key = k; 190*e2553d68SSerge Dussud if (indprev == NULL) 191*e2553d68SSerge Dussud index = ind; 192*e2553d68SSerge Dussud else 193*e2553d68SSerge Dussud indprev->right = ind; 1947c478bd9Sstevel@tonic-gate indprev = ind; } 1957c478bd9Sstevel@tonic-gate /* create last dummy notice */ 1967c478bd9Sstevel@tonic-gate n = (struct notice *)xmalloc(sizeof (struct notice)); 1977c478bd9Sstevel@tonic-gate n->time = INFINITY; 1987c478bd9Sstevel@tonic-gate n->isdummy = TRUE; 1997c478bd9Sstevel@tonic-gate n->left = nprev; 2007c478bd9Sstevel@tonic-gate n->right = NULL; 2017c478bd9Sstevel@tonic-gate nprev->right = n; 2027c478bd9Sstevel@tonic-gate /* create last dummy key */ 2037c478bd9Sstevel@tonic-gate k = (struct key *)xmalloc(sizeof (struct key)); 2047c478bd9Sstevel@tonic-gate k->time = INFINITY; 2057c478bd9Sstevel@tonic-gate k->numnote = 1; 2067c478bd9Sstevel@tonic-gate k->notice = n; 2077c478bd9Sstevel@tonic-gate k->left = kprev; 2087c478bd9Sstevel@tonic-gate k->right = NULL; 2097c478bd9Sstevel@tonic-gate kprev->right = k; 2107c478bd9Sstevel@tonic-gate n->key = k; 2117c478bd9Sstevel@tonic-gate /* create last index element */ 2127c478bd9Sstevel@tonic-gate ind = (struct index *)xmalloc(sizeof (struct index)); 2137c478bd9Sstevel@tonic-gate ind->key = k; 2147c478bd9Sstevel@tonic-gate ind->right = NULL; 2157c478bd9Sstevel@tonic-gate indprev->right = ind; 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate current = NULL; 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate 221*e2553d68SSerge Dussud /* ********************** */ 222*e2553d68SSerge Dussud int 2237c478bd9Sstevel@tonic-gate el_add(event, time, id) 224*e2553d68SSerge Dussud /* ********************** */ 2257c478bd9Sstevel@tonic-gate void *event; 2267c478bd9Sstevel@tonic-gate int id; 2277c478bd9Sstevel@tonic-gate time_t time; 2287c478bd9Sstevel@tonic-gate { 229*e2553d68SSerge Dussud /* 230*e2553d68SSerge Dussud * add works slightly differently than in the reference. if the 231*e2553d68SSerge Dussud * sublist to be inserted into is full (numnote = NLIM), 232*e2553d68SSerge Dussud * the sublist is split in half. thus the size of the sublists 233*e2553d68SSerge Dussud * in this implementation normally ranges from NLIM/2 to NLIM. 234*e2553d68SSerge Dussud */ 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate struct index *ind; 2377c478bd9Sstevel@tonic-gate struct key *k, *k2; 2387c478bd9Sstevel@tonic-gate struct notice *n, *n2; 2397c478bd9Sstevel@tonic-gate int i; 2407c478bd9Sstevel@tonic-gate 241*e2553d68SSerge Dussud /* 242*e2553d68SSerge Dussud * time may be 0 when set by next_time() on error or an 243*e2553d68SSerge Dussud * invalid time specification of job 244*e2553d68SSerge Dussud */ 245*e2553d68SSerge Dussud if ((index == NULL) || (time <= 0)) { 246*e2553d68SSerge Dussud return (-1); 247*e2553d68SSerge Dussud } 248*e2553d68SSerge Dussud if (time < LB) { 249*e2553d68SSerge Dussud return (-2); 250*e2553d68SSerge Dussud } 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate /* allocate new notice */ 2537c478bd9Sstevel@tonic-gate n = (struct notice *)xmalloc(sizeof (struct notice)); 2547c478bd9Sstevel@tonic-gate n->time = time; 2557c478bd9Sstevel@tonic-gate n->id = id; 2567c478bd9Sstevel@tonic-gate n->event = event; 2577c478bd9Sstevel@tonic-gate n->isdummy = FALSE; 2587c478bd9Sstevel@tonic-gate n->key = NULL; 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate /* find the right interval */ 2617c478bd9Sstevel@tonic-gate ind = index; 2627c478bd9Sstevel@tonic-gate while ((ind->key)->time <= time) ind = ind->right; 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* find the right key */ 2657c478bd9Sstevel@tonic-gate k = (ind->key)->left; 2667c478bd9Sstevel@tonic-gate while (k->time > time) k = k->left; 2677c478bd9Sstevel@tonic-gate k = k->right; 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate /* (k->time>time) and ((k->left)->time<=time) */ 2707c478bd9Sstevel@tonic-gate if (k->numnote == NLIM) { 2717c478bd9Sstevel@tonic-gate /* k's sublist is full, so split it */ 2727c478bd9Sstevel@tonic-gate k->numnote = NLIM / 2; 2737c478bd9Sstevel@tonic-gate n2 = k->notice; 2747c478bd9Sstevel@tonic-gate for (i = 1; i <= NLIM/2; i++) n2 = n2->left; 2757c478bd9Sstevel@tonic-gate /* create a key which will point to notice n2 */ 2767c478bd9Sstevel@tonic-gate k2 = (struct key *)xmalloc(sizeof (struct key)); 2777c478bd9Sstevel@tonic-gate k2->time = n2->time; 2787c478bd9Sstevel@tonic-gate k2->numnote = NLIM - NLIM/2; 2797c478bd9Sstevel@tonic-gate k2->notice = n2; 2807c478bd9Sstevel@tonic-gate k2->right = k; 2817c478bd9Sstevel@tonic-gate k2->left = k->left; 2827c478bd9Sstevel@tonic-gate k->left = k2; 2837c478bd9Sstevel@tonic-gate (k2->left)->right = k2; 2847c478bd9Sstevel@tonic-gate n2->key = k2; /* have n2 point back to k2 */ 2857c478bd9Sstevel@tonic-gate /* which of the new sublists will hold the new notice? */ 2867c478bd9Sstevel@tonic-gate if (k2->time > time) k = k2; } 2877c478bd9Sstevel@tonic-gate 288*e2553d68SSerge Dussud /* 289*e2553d68SSerge Dussud * the new notice n is ready to be inserted 290*e2553d68SSerge Dussud * k points to the appropriate sublist 291*e2553d68SSerge Dussud */ 2927c478bd9Sstevel@tonic-gate k->numnote = k->numnote + 1; 2937c478bd9Sstevel@tonic-gate n2 = k->notice; 2947c478bd9Sstevel@tonic-gate while (n2->time > time) n2 = n2->left; 2957c478bd9Sstevel@tonic-gate n->right = n2->right; 2967c478bd9Sstevel@tonic-gate n->left = n2; 2977c478bd9Sstevel@tonic-gate (n2->right)->left = n; 2987c478bd9Sstevel@tonic-gate n2->right = n; 2997c478bd9Sstevel@tonic-gate 300*e2553d68SSerge Dussud if ((current == NULL) || (current->time > time)) 301*e2553d68SSerge Dussud current = n; 302*e2553d68SSerge Dussud 303*e2553d68SSerge Dussud return (0); 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate 307*e2553d68SSerge Dussud /* ******************** */ 3087c478bd9Sstevel@tonic-gate void 3097c478bd9Sstevel@tonic-gate el_remove(id, flag) 310*e2553d68SSerge Dussud /* ******************** */ 3117c478bd9Sstevel@tonic-gate int id, flag; 3127c478bd9Sstevel@tonic-gate { 313*e2553d68SSerge Dussud /* 314*e2553d68SSerge Dussud * remove finds notices n that need to be removed by traversing thru 315*e2553d68SSerge Dussud * the notice list. if n is the sole element of a sublist, the 316*e2553d68SSerge Dussud * sublist is deleted. if not, an adjacent sublist is merged with 317*e2553d68SSerge Dussud * n's sublist, if that is possible. after these checks, n is removed. 318*e2553d68SSerge Dussud */ 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate struct notice *n, *n2; 3217c478bd9Sstevel@tonic-gate struct key *k, *kl, *kr; 3227c478bd9Sstevel@tonic-gate 323*e2553d68SSerge Dussud if ((index == NULL) || (current == NULL)) 324*e2553d68SSerge Dussud return; 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate n = current; 3277c478bd9Sstevel@tonic-gate while (n != NULL) { 328*e2553d68SSerge Dussud while ((n != NULL) && ((n->isdummy) || (n->id != id))) 329*e2553d68SSerge Dussud n = n->right; 3307c478bd9Sstevel@tonic-gate if (n != NULL) { 3317c478bd9Sstevel@tonic-gate /* n should be deleted */ 3327c478bd9Sstevel@tonic-gate if ((n->key != NULL) && ((n->key)->numnote == 1)) { 3337c478bd9Sstevel@tonic-gate /* n = sole element of a sublist */ 3347c478bd9Sstevel@tonic-gate k = n->key; 3357c478bd9Sstevel@tonic-gate (k->left)->right = k->right; 3367c478bd9Sstevel@tonic-gate (k->right)->left = k->left; 337*e2553d68SSerge Dussud free(k); 338*e2553d68SSerge Dussud } else { if (n->key != NULL) { 3397c478bd9Sstevel@tonic-gate /* n has a key pointing to it */ 3407c478bd9Sstevel@tonic-gate (n->left)->key = n->key; 3417c478bd9Sstevel@tonic-gate (n->key)->time = (n->left)->time; 3427c478bd9Sstevel@tonic-gate (n->key)->notice = n->left; } 3437c478bd9Sstevel@tonic-gate /* find the key that points to this sublist */ 3447c478bd9Sstevel@tonic-gate n2 = n; 3457c478bd9Sstevel@tonic-gate while (n2->key == NULL) n2 = n2->right; 3467c478bd9Sstevel@tonic-gate k = n2->key; 3477c478bd9Sstevel@tonic-gate k->numnote = k->numnote - 1; 348*e2553d68SSerge Dussud /* 349*e2553d68SSerge Dussud * check if two adjacent sublists can be merged 350*e2553d68SSerge Dussud * first check left, then check right 351*e2553d68SSerge Dussud */ 3527c478bd9Sstevel@tonic-gate kl = k->left; 3537c478bd9Sstevel@tonic-gate kr = k->right; 3547c478bd9Sstevel@tonic-gate if ((!(kl->notice)->isdummy) && 3557c478bd9Sstevel@tonic-gate ((kl->numnote+k->numnote) <= NLIM)) { 3567c478bd9Sstevel@tonic-gate /* delete the key to the left */ 3577c478bd9Sstevel@tonic-gate (kl->notice)->key = NULL; 3587c478bd9Sstevel@tonic-gate k->numnote += kl->numnote; 3597c478bd9Sstevel@tonic-gate (kl->left)->right = k; 3607c478bd9Sstevel@tonic-gate k->left = kl->left; 361*e2553d68SSerge Dussud free(kl); 362*e2553d68SSerge Dussud } else if ((!(k->notice)->isdummy) && 363*e2553d68SSerge Dussud ((kr->numnote+k->numnote) 364*e2553d68SSerge Dussud <= NLIM)) { 3657c478bd9Sstevel@tonic-gate /* delete this key */ 3667c478bd9Sstevel@tonic-gate (k->notice)->key = NULL; 3677c478bd9Sstevel@tonic-gate kr->numnote += k->numnote; 3687c478bd9Sstevel@tonic-gate (k->left)->right = kr; 3697c478bd9Sstevel@tonic-gate kr->left = k->left; 3707c478bd9Sstevel@tonic-gate free(k); } 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate /* delete n, then advance n down the list */ 3737c478bd9Sstevel@tonic-gate (n->left)->right = n->right; 3747c478bd9Sstevel@tonic-gate (n->right)->left = n->left; 3757c478bd9Sstevel@tonic-gate n2 = n->right; 3767c478bd9Sstevel@tonic-gate free(n); 3777c478bd9Sstevel@tonic-gate n = n2; 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate if (flag) break; 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate /* now reset current */ 3827c478bd9Sstevel@tonic-gate k = (index->key)->left; 3837c478bd9Sstevel@tonic-gate while (k->left != NULL) k = k->left; 3847c478bd9Sstevel@tonic-gate n = (k->notice)->right; 3857c478bd9Sstevel@tonic-gate while ((n != NULL) && (n->isdummy)) n = n->right; 3867c478bd9Sstevel@tonic-gate current = n; 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate 390*e2553d68SSerge Dussud /* ********************* */ 391032624d5Sbasabi int 392032624d5Sbasabi el_empty(void) 393*e2553d68SSerge Dussud /* ********************* */ 3947c478bd9Sstevel@tonic-gate { 395*e2553d68SSerge Dussud if (current == NULL) 396*e2553d68SSerge Dussud return (1); 397*e2553d68SSerge Dussud else 398*e2553d68SSerge Dussud return (0); 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate 402*e2553d68SSerge Dussud /* ********************* */ 4037c478bd9Sstevel@tonic-gate void * 404032624d5Sbasabi el_first(void) 405*e2553d68SSerge Dussud /* ********************* */ 4067c478bd9Sstevel@tonic-gate { 4077c478bd9Sstevel@tonic-gate struct notice *n, *fn; 4087c478bd9Sstevel@tonic-gate struct key *k, *fk; 4097c478bd9Sstevel@tonic-gate struct index *ind, *fi; 4107c478bd9Sstevel@tonic-gate int ctr, *val; 4117c478bd9Sstevel@tonic-gate time_t next_int; 4127c478bd9Sstevel@tonic-gate 413*e2553d68SSerge Dussud if ((index == NULL) || (current == NULL)) 414*e2553d68SSerge Dussud return (NULL); 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate while ((index->key)->time < current->time) { 4177c478bd9Sstevel@tonic-gate if (DU == 2) { 4187c478bd9Sstevel@tonic-gate /* only two intervals, so relabel first one */ 4197c478bd9Sstevel@tonic-gate k = index->key; 4207c478bd9Sstevel@tonic-gate k->time += DT; 4217c478bd9Sstevel@tonic-gate (k->notice)->time += DT; 4227c478bd9Sstevel@tonic-gate continue; } 423*e2553d68SSerge Dussud /* 424*e2553d68SSerge Dussud * remove the notice, key, and index corresponding 425*e2553d68SSerge Dussud * to the first time interval. Then split the 426*e2553d68SSerge Dussud * overflow interval into a normal interval 427*e2553d68SSerge Dussud * plus an overflow interval. 428*e2553d68SSerge Dussud */ 4297c478bd9Sstevel@tonic-gate fi = index; 4307c478bd9Sstevel@tonic-gate fk = fi->key; 4317c478bd9Sstevel@tonic-gate fn = fk->notice; 4327c478bd9Sstevel@tonic-gate (fn->left)->right = fn->right; 4337c478bd9Sstevel@tonic-gate (fn->right)->left = fn->left; 4347c478bd9Sstevel@tonic-gate (fk->left)->right = fk->right; 4357c478bd9Sstevel@tonic-gate (fk->right)->left = fk->left; 4367c478bd9Sstevel@tonic-gate index = index->right; 4377c478bd9Sstevel@tonic-gate /* find where to split */ 4387c478bd9Sstevel@tonic-gate ind = index; 4397c478bd9Sstevel@tonic-gate while ((ind->right)->right != NULL) ind = ind->right; 4407c478bd9Sstevel@tonic-gate /* ind points to the next to last index interval */ 4417c478bd9Sstevel@tonic-gate k = ind->key; 4427c478bd9Sstevel@tonic-gate next_int = k->time + DT; /* upper bound on new inter. */ 4437c478bd9Sstevel@tonic-gate while (k->time < next_int) k = k->right; 4447c478bd9Sstevel@tonic-gate /* k points to the appropriate sublist of notices */ 4457c478bd9Sstevel@tonic-gate n = (k->notice)->left; 4467c478bd9Sstevel@tonic-gate ctr = 1; 4477c478bd9Sstevel@tonic-gate while (n->time >= next_int) { 4487c478bd9Sstevel@tonic-gate ctr++; 4497c478bd9Sstevel@tonic-gate n = n->left; } 4507c478bd9Sstevel@tonic-gate n = n->right; 451*e2553d68SSerge Dussud /* 452*e2553d68SSerge Dussud * n points to first notice of the new overflow interval 453*e2553d68SSerge Dussud * ctr tells how many notices are in the first sublist 454*e2553d68SSerge Dussud * of the new overflow interval 455*e2553d68SSerge Dussud * insert the new index element 456*e2553d68SSerge Dussud */ 4577c478bd9Sstevel@tonic-gate fi->right = ind->right; 4587c478bd9Sstevel@tonic-gate ind->right = fi; 4597c478bd9Sstevel@tonic-gate /* insert the new dummy key */ 4607c478bd9Sstevel@tonic-gate fk->time = next_int; 4617c478bd9Sstevel@tonic-gate fk->numnote = k->numnote - ctr + 1; 4627c478bd9Sstevel@tonic-gate fk->left = k->left; 4637c478bd9Sstevel@tonic-gate fk->right = k; 4647c478bd9Sstevel@tonic-gate (k->left)->right = fk; 4657c478bd9Sstevel@tonic-gate k->left = fk; 4667c478bd9Sstevel@tonic-gate k->numnote = ctr; 4677c478bd9Sstevel@tonic-gate /* insert the new dummy notice */ 4687c478bd9Sstevel@tonic-gate fn->time = next_int; 4697c478bd9Sstevel@tonic-gate fn->left = n->left; 4707c478bd9Sstevel@tonic-gate fn->right = n; 4717c478bd9Sstevel@tonic-gate (n->left)->right = fn; 4727c478bd9Sstevel@tonic-gate n->left = fn; } 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate /* remove the first element of the list */ 4757c478bd9Sstevel@tonic-gate (current->left)->right = current->right; 4767c478bd9Sstevel@tonic-gate (current->right)->left = current->left; 4777c478bd9Sstevel@tonic-gate /* now update the numnote field in the appropriate key */ 4787c478bd9Sstevel@tonic-gate n = current; 4797c478bd9Sstevel@tonic-gate while (n->key == NULL) n = n->right; 4807c478bd9Sstevel@tonic-gate k = n->key; 4817c478bd9Sstevel@tonic-gate k->numnote = k->numnote - 1; 4827c478bd9Sstevel@tonic-gate /* if numnote = 0 then this key must be removed */ 4837c478bd9Sstevel@tonic-gate if (k->numnote == 0) { 4847c478bd9Sstevel@tonic-gate (k->left)->right = k->right; 4857c478bd9Sstevel@tonic-gate (k->right)->left = k->left; 4867c478bd9Sstevel@tonic-gate free(k); } 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate /* now set current to be the head of the list */ 4897c478bd9Sstevel@tonic-gate fn = current->right; 4907c478bd9Sstevel@tonic-gate while ((fn != NULL) && (fn->isdummy)) 4917c478bd9Sstevel@tonic-gate fn = fn->right; 4927c478bd9Sstevel@tonic-gate val = current->event; 4937c478bd9Sstevel@tonic-gate free(current); 4947c478bd9Sstevel@tonic-gate current = fn; 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate return (val); 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate 500*e2553d68SSerge Dussud /* ************** */ 5017c478bd9Sstevel@tonic-gate void 502032624d5Sbasabi el_delete(void) 503*e2553d68SSerge Dussud /* ************** */ 5047c478bd9Sstevel@tonic-gate { 5057c478bd9Sstevel@tonic-gate /* el_delete frees up all the space associated with the event list */ 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate struct index *ind, *ind2; 5087c478bd9Sstevel@tonic-gate struct key *k, *k2; 5097c478bd9Sstevel@tonic-gate struct notice *n, *n2; 5107c478bd9Sstevel@tonic-gate 511*e2553d68SSerge Dussud if (index == NULL) 512*e2553d68SSerge Dussud return; 5137c478bd9Sstevel@tonic-gate ind = index; 5147c478bd9Sstevel@tonic-gate k = ind->key; 5157c478bd9Sstevel@tonic-gate while (k->left != NULL) k = k->left; 5167c478bd9Sstevel@tonic-gate n = k->notice; 5177c478bd9Sstevel@tonic-gate while (n != NULL) { 5187c478bd9Sstevel@tonic-gate n2 = n->right; 5197c478bd9Sstevel@tonic-gate free(n); 5207c478bd9Sstevel@tonic-gate n = n2; } 5217c478bd9Sstevel@tonic-gate while (k != NULL) { 5227c478bd9Sstevel@tonic-gate k2 = k->right; 5237c478bd9Sstevel@tonic-gate free(k); 5247c478bd9Sstevel@tonic-gate k = k2; } 5257c478bd9Sstevel@tonic-gate while (ind != NULL) { 5267c478bd9Sstevel@tonic-gate ind2 = ind->right; 5277c478bd9Sstevel@tonic-gate free(ind); 5287c478bd9Sstevel@tonic-gate ind = ind2; } 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate index = NULL; 5317c478bd9Sstevel@tonic-gate current = NULL; 5327c478bd9Sstevel@tonic-gate } 533