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 TRUE 1 677c478bd9Sstevel@tonic-gate #define FALSE 0 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate /* the following parameters are set in init */ 707c478bd9Sstevel@tonic-gate static int DU; /* number of time intervals */ 717c478bd9Sstevel@tonic-gate static time_t LB; /* lower bound on time */ 727c478bd9Sstevel@tonic-gate static time_t DT; /* width of interval */ 737c478bd9Sstevel@tonic-gate static int NLIM; /* max notices per sublist */ 747c478bd9Sstevel@tonic-gate 75*e2553d68SSerge Dussud /* 76*e2553d68SSerge Dussud * a notice points to an event. a notice has the following fields: 77*e2553d68SSerge Dussud * time = time of the event. 78*e2553d68SSerge Dussud * id = identifier for an event or class of events that may need 79*e2553d68SSerge Dussud * to be removed (other than at the front of the list). 80*e2553d68SSerge Dussud * event = pointer to the event. 81*e2553d68SSerge Dussud * isdummy = tells whether this notice points to a real event or 82*e2553d68SSerge Dussud * is just a dummy notice (one that is used to "mark off" 83*e2553d68SSerge Dussud * the time intervals that the user specifies in init). 84*e2553d68SSerge Dussud * key = points back to the key that points to this notice, 85*e2553d68SSerge Dussud * if there is one. 86*e2553d68SSerge Dussud * left = points to the notice immediately preceding this one. 87*e2553d68SSerge Dussud * right = points to the notice immediately following this one. 88*e2553d68SSerge Dussud */ 897c478bd9Sstevel@tonic-gate struct notice { time_t time; 907c478bd9Sstevel@tonic-gate int id; 917c478bd9Sstevel@tonic-gate void *event; 927c478bd9Sstevel@tonic-gate short int isdummy; 937c478bd9Sstevel@tonic-gate struct key *key; 947c478bd9Sstevel@tonic-gate struct notice *left; 957c478bd9Sstevel@tonic-gate struct notice *right; }; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate /* current points to the front of the list of notices (events) */ 987c478bd9Sstevel@tonic-gate struct notice *current = NULL; 997c478bd9Sstevel@tonic-gate 100*e2553d68SSerge Dussud /* 101*e2553d68SSerge Dussud * a key points to a sublist of notices. a key has the following fields: 102*e2553d68SSerge Dussud * time = max time of notices in sublist. 103*e2553d68SSerge Dussud * numnote = number of notices in sublist. 104*e2553d68SSerge Dussud * notice = pointer to the notice with max time. 105*e2553d68SSerge Dussud * left = points to the key immediately preceding this one. 106*e2553d68SSerge Dussud * right = points to the key immediately following this one. 107*e2553d68SSerge Dussud */ 1087c478bd9Sstevel@tonic-gate struct key { time_t time; 1097c478bd9Sstevel@tonic-gate int numnote; 1107c478bd9Sstevel@tonic-gate struct notice *notice; 1117c478bd9Sstevel@tonic-gate struct key *left; 1127c478bd9Sstevel@tonic-gate struct key *right; }; 1137c478bd9Sstevel@tonic-gate 114*e2553d68SSerge Dussud /* 115*e2553d68SSerge Dussud * the index list breaks the keys into time intervals as specified in init. 116*e2553d68SSerge Dussud * the index is "shifted" one time interval whenever el_first returns an 117*e2553d68SSerge Dussud * event with a time greater than the max time of the first interval 118*e2553d68SSerge Dussud * (eg. with intervals of a day which span one week (MTWTFSS), 119*e2553d68SSerge Dussud * if el_first finds the next event is on tuesday, then 120*e2553d68SSerge Dussud * the intervals of the event list get shifted (TWTFSSM). 121*e2553d68SSerge Dussud */ 1227c478bd9Sstevel@tonic-gate struct index { struct key *key; 1237c478bd9Sstevel@tonic-gate struct index *right; }; 1247c478bd9Sstevel@tonic-gate 125*e2553d68SSerge Dussud /* index pts to the front of the index list */ 126*e2553d68SSerge Dussud static struct index *index = NULL; 1277c478bd9Sstevel@tonic-gate 128*e2553d68SSerge Dussud /* ******************* */ 1297c478bd9Sstevel@tonic-gate void 1307c478bd9Sstevel@tonic-gate el_init(du, lb, dt, nlim) 131*e2553d68SSerge Dussud /* ******************* */ 1327c478bd9Sstevel@tonic-gate int du, nlim; 1337c478bd9Sstevel@tonic-gate time_t lb, dt; 1347c478bd9Sstevel@tonic-gate { 1357c478bd9Sstevel@tonic-gate int i; 1367c478bd9Sstevel@tonic-gate time_t t; 1377c478bd9Sstevel@tonic-gate struct index *indprev, *ind; 1387c478bd9Sstevel@tonic-gate struct key *kprev, *k; 1397c478bd9Sstevel@tonic-gate struct notice *nprev, *n; 1407c478bd9Sstevel@tonic-gate 141*e2553d68SSerge Dussud if ((du < 1) || (dt < 1) || (nlim < 1)) 142*e2553d68SSerge Dussud return; 1437c478bd9Sstevel@tonic-gate DU = du + 1; 1447c478bd9Sstevel@tonic-gate LB = lb; 1457c478bd9Sstevel@tonic-gate DT = dt; 1467c478bd9Sstevel@tonic-gate NLIM = nlim; 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate /* 1497c478bd9Sstevel@tonic-gate * initialize index, keys, and notices 1507c478bd9Sstevel@tonic-gate */ 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate /* create first dummy notice */ 1537c478bd9Sstevel@tonic-gate n = (struct notice *)xmalloc(sizeof (struct notice)); 1547c478bd9Sstevel@tonic-gate n->time = LB; 1557c478bd9Sstevel@tonic-gate n->isdummy = TRUE; 1567c478bd9Sstevel@tonic-gate n->left = NULL; 1577c478bd9Sstevel@tonic-gate nprev = n; 1587c478bd9Sstevel@tonic-gate /* create first dummy key */ 1597c478bd9Sstevel@tonic-gate k = (struct key *)xmalloc(sizeof (struct key)); 1607c478bd9Sstevel@tonic-gate k->time = LB; 1617c478bd9Sstevel@tonic-gate k->numnote = 1; 1627c478bd9Sstevel@tonic-gate k->notice = n; 1637c478bd9Sstevel@tonic-gate k->left = NULL; 1647c478bd9Sstevel@tonic-gate kprev = k; 1657c478bd9Sstevel@tonic-gate /* make notice point to key */ 1667c478bd9Sstevel@tonic-gate n->key = k; 1677c478bd9Sstevel@tonic-gate /* no index element to allocate this time */ 1687c478bd9Sstevel@tonic-gate indprev = NULL; 1697c478bd9Sstevel@tonic-gate /* create dummy notices, dummy keys, and index elements */ 1707c478bd9Sstevel@tonic-gate t = LB; 1717c478bd9Sstevel@tonic-gate for (i = 1; i < DU; i++) { 1727c478bd9Sstevel@tonic-gate t = t + DT; 1737c478bd9Sstevel@tonic-gate n = (struct notice *)xmalloc(sizeof (struct notice)); 1747c478bd9Sstevel@tonic-gate n->time = t; 1757c478bd9Sstevel@tonic-gate n->isdummy = TRUE; 1767c478bd9Sstevel@tonic-gate n->left = nprev; 1777c478bd9Sstevel@tonic-gate nprev->right = n; 1787c478bd9Sstevel@tonic-gate nprev = n; 1797c478bd9Sstevel@tonic-gate k = (struct key *)xmalloc(sizeof (struct key)); 1807c478bd9Sstevel@tonic-gate k->time = t; 1817c478bd9Sstevel@tonic-gate k->numnote = 1; 1827c478bd9Sstevel@tonic-gate k->notice = n; 1837c478bd9Sstevel@tonic-gate k->left = kprev; 1847c478bd9Sstevel@tonic-gate kprev->right = k; 1857c478bd9Sstevel@tonic-gate kprev = k; 1867c478bd9Sstevel@tonic-gate n->key = k; 1877c478bd9Sstevel@tonic-gate ind = (struct index *)xmalloc(sizeof (struct index)); 1887c478bd9Sstevel@tonic-gate ind->key = k; 189*e2553d68SSerge Dussud if (indprev == NULL) 190*e2553d68SSerge Dussud index = ind; 191*e2553d68SSerge Dussud else 192*e2553d68SSerge Dussud indprev->right = ind; 1937c478bd9Sstevel@tonic-gate indprev = ind; } 1947c478bd9Sstevel@tonic-gate /* create last dummy notice */ 1957c478bd9Sstevel@tonic-gate n = (struct notice *)xmalloc(sizeof (struct notice)); 1967c478bd9Sstevel@tonic-gate n->time = INFINITY; 1977c478bd9Sstevel@tonic-gate n->isdummy = TRUE; 1987c478bd9Sstevel@tonic-gate n->left = nprev; 1997c478bd9Sstevel@tonic-gate n->right = NULL; 2007c478bd9Sstevel@tonic-gate nprev->right = n; 2017c478bd9Sstevel@tonic-gate /* create last dummy key */ 2027c478bd9Sstevel@tonic-gate k = (struct key *)xmalloc(sizeof (struct key)); 2037c478bd9Sstevel@tonic-gate k->time = INFINITY; 2047c478bd9Sstevel@tonic-gate k->numnote = 1; 2057c478bd9Sstevel@tonic-gate k->notice = n; 2067c478bd9Sstevel@tonic-gate k->left = kprev; 2077c478bd9Sstevel@tonic-gate k->right = NULL; 2087c478bd9Sstevel@tonic-gate kprev->right = k; 2097c478bd9Sstevel@tonic-gate n->key = k; 2107c478bd9Sstevel@tonic-gate /* create last index element */ 2117c478bd9Sstevel@tonic-gate ind = (struct index *)xmalloc(sizeof (struct index)); 2127c478bd9Sstevel@tonic-gate ind->key = k; 2137c478bd9Sstevel@tonic-gate ind->right = NULL; 2147c478bd9Sstevel@tonic-gate indprev->right = ind; 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate current = NULL; 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate 220*e2553d68SSerge Dussud /* ********************** */ 221*e2553d68SSerge Dussud int 2227c478bd9Sstevel@tonic-gate el_add(event, time, id) 223*e2553d68SSerge Dussud /* ********************** */ 2247c478bd9Sstevel@tonic-gate void *event; 2257c478bd9Sstevel@tonic-gate int id; 2267c478bd9Sstevel@tonic-gate time_t time; 2277c478bd9Sstevel@tonic-gate { 228*e2553d68SSerge Dussud /* 229*e2553d68SSerge Dussud * add works slightly differently than in the reference. if the 230*e2553d68SSerge Dussud * sublist to be inserted into is full (numnote = NLIM), 231*e2553d68SSerge Dussud * the sublist is split in half. thus the size of the sublists 232*e2553d68SSerge Dussud * in this implementation normally ranges from NLIM/2 to NLIM. 233*e2553d68SSerge Dussud */ 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate struct index *ind; 2367c478bd9Sstevel@tonic-gate struct key *k, *k2; 2377c478bd9Sstevel@tonic-gate struct notice *n, *n2; 2387c478bd9Sstevel@tonic-gate int i; 2397c478bd9Sstevel@tonic-gate 240*e2553d68SSerge Dussud /* 241*e2553d68SSerge Dussud * time may be 0 when set by next_time() on error or an 242*e2553d68SSerge Dussud * invalid time specification of job 243*e2553d68SSerge Dussud */ 244*e2553d68SSerge Dussud if ((index == NULL) || (time <= 0)) { 245*e2553d68SSerge Dussud return (-1); 246*e2553d68SSerge Dussud } 247*e2553d68SSerge Dussud if (time < LB) { 248*e2553d68SSerge Dussud return (-2); 249*e2553d68SSerge Dussud } 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate /* allocate new notice */ 2527c478bd9Sstevel@tonic-gate n = (struct notice *)xmalloc(sizeof (struct notice)); 2537c478bd9Sstevel@tonic-gate n->time = time; 2547c478bd9Sstevel@tonic-gate n->id = id; 2557c478bd9Sstevel@tonic-gate n->event = event; 2567c478bd9Sstevel@tonic-gate n->isdummy = FALSE; 2577c478bd9Sstevel@tonic-gate n->key = NULL; 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate /* find the right interval */ 2607c478bd9Sstevel@tonic-gate ind = index; 2617c478bd9Sstevel@tonic-gate while ((ind->key)->time <= time) ind = ind->right; 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate /* find the right key */ 2647c478bd9Sstevel@tonic-gate k = (ind->key)->left; 2657c478bd9Sstevel@tonic-gate while (k->time > time) k = k->left; 2667c478bd9Sstevel@tonic-gate k = k->right; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate /* (k->time>time) and ((k->left)->time<=time) */ 2697c478bd9Sstevel@tonic-gate if (k->numnote == NLIM) { 2707c478bd9Sstevel@tonic-gate /* k's sublist is full, so split it */ 2717c478bd9Sstevel@tonic-gate k->numnote = NLIM / 2; 2727c478bd9Sstevel@tonic-gate n2 = k->notice; 2737c478bd9Sstevel@tonic-gate for (i = 1; i <= NLIM/2; i++) n2 = n2->left; 2747c478bd9Sstevel@tonic-gate /* create a key which will point to notice n2 */ 2757c478bd9Sstevel@tonic-gate k2 = (struct key *)xmalloc(sizeof (struct key)); 2767c478bd9Sstevel@tonic-gate k2->time = n2->time; 2777c478bd9Sstevel@tonic-gate k2->numnote = NLIM - NLIM/2; 2787c478bd9Sstevel@tonic-gate k2->notice = n2; 2797c478bd9Sstevel@tonic-gate k2->right = k; 2807c478bd9Sstevel@tonic-gate k2->left = k->left; 2817c478bd9Sstevel@tonic-gate k->left = k2; 2827c478bd9Sstevel@tonic-gate (k2->left)->right = k2; 2837c478bd9Sstevel@tonic-gate n2->key = k2; /* have n2 point back to k2 */ 2847c478bd9Sstevel@tonic-gate /* which of the new sublists will hold the new notice? */ 2857c478bd9Sstevel@tonic-gate if (k2->time > time) k = k2; } 2867c478bd9Sstevel@tonic-gate 287*e2553d68SSerge Dussud /* 288*e2553d68SSerge Dussud * the new notice n is ready to be inserted 289*e2553d68SSerge Dussud * k points to the appropriate sublist 290*e2553d68SSerge Dussud */ 2917c478bd9Sstevel@tonic-gate k->numnote = k->numnote + 1; 2927c478bd9Sstevel@tonic-gate n2 = k->notice; 2937c478bd9Sstevel@tonic-gate while (n2->time > time) n2 = n2->left; 2947c478bd9Sstevel@tonic-gate n->right = n2->right; 2957c478bd9Sstevel@tonic-gate n->left = n2; 2967c478bd9Sstevel@tonic-gate (n2->right)->left = n; 2977c478bd9Sstevel@tonic-gate n2->right = n; 2987c478bd9Sstevel@tonic-gate 299*e2553d68SSerge Dussud if ((current == NULL) || (current->time > time)) 300*e2553d68SSerge Dussud current = n; 301*e2553d68SSerge Dussud 302*e2553d68SSerge Dussud return (0); 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate 306*e2553d68SSerge Dussud /* ******************** */ 3077c478bd9Sstevel@tonic-gate void 3087c478bd9Sstevel@tonic-gate el_remove(id, flag) 309*e2553d68SSerge Dussud /* ******************** */ 3107c478bd9Sstevel@tonic-gate int id, flag; 3117c478bd9Sstevel@tonic-gate { 312*e2553d68SSerge Dussud /* 313*e2553d68SSerge Dussud * remove finds notices n that need to be removed by traversing thru 314*e2553d68SSerge Dussud * the notice list. if n is the sole element of a sublist, the 315*e2553d68SSerge Dussud * sublist is deleted. if not, an adjacent sublist is merged with 316*e2553d68SSerge Dussud * n's sublist, if that is possible. after these checks, n is removed. 317*e2553d68SSerge Dussud */ 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate struct notice *n, *n2; 3207c478bd9Sstevel@tonic-gate struct key *k, *kl, *kr; 3217c478bd9Sstevel@tonic-gate 322*e2553d68SSerge Dussud if ((index == NULL) || (current == NULL)) 323*e2553d68SSerge Dussud return; 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate n = current; 3267c478bd9Sstevel@tonic-gate while (n != NULL) { 327*e2553d68SSerge Dussud while ((n != NULL) && ((n->isdummy) || (n->id != id))) 328*e2553d68SSerge Dussud n = n->right; 3297c478bd9Sstevel@tonic-gate if (n != NULL) { 3307c478bd9Sstevel@tonic-gate /* n should be deleted */ 3317c478bd9Sstevel@tonic-gate if ((n->key != NULL) && ((n->key)->numnote == 1)) { 3327c478bd9Sstevel@tonic-gate /* n = sole element of a sublist */ 3337c478bd9Sstevel@tonic-gate k = n->key; 3347c478bd9Sstevel@tonic-gate (k->left)->right = k->right; 3357c478bd9Sstevel@tonic-gate (k->right)->left = k->left; 336*e2553d68SSerge Dussud free(k); 337*e2553d68SSerge Dussud } else { if (n->key != NULL) { 3387c478bd9Sstevel@tonic-gate /* n has a key pointing to it */ 3397c478bd9Sstevel@tonic-gate (n->left)->key = n->key; 3407c478bd9Sstevel@tonic-gate (n->key)->time = (n->left)->time; 3417c478bd9Sstevel@tonic-gate (n->key)->notice = n->left; } 3427c478bd9Sstevel@tonic-gate /* find the key that points to this sublist */ 3437c478bd9Sstevel@tonic-gate n2 = n; 3447c478bd9Sstevel@tonic-gate while (n2->key == NULL) n2 = n2->right; 3457c478bd9Sstevel@tonic-gate k = n2->key; 3467c478bd9Sstevel@tonic-gate k->numnote = k->numnote - 1; 347*e2553d68SSerge Dussud /* 348*e2553d68SSerge Dussud * check if two adjacent sublists can be merged 349*e2553d68SSerge Dussud * first check left, then check right 350*e2553d68SSerge Dussud */ 3517c478bd9Sstevel@tonic-gate kl = k->left; 3527c478bd9Sstevel@tonic-gate kr = k->right; 3537c478bd9Sstevel@tonic-gate if ((!(kl->notice)->isdummy) && 3547c478bd9Sstevel@tonic-gate ((kl->numnote+k->numnote) <= NLIM)) { 3557c478bd9Sstevel@tonic-gate /* delete the key to the left */ 3567c478bd9Sstevel@tonic-gate (kl->notice)->key = NULL; 3577c478bd9Sstevel@tonic-gate k->numnote += kl->numnote; 3587c478bd9Sstevel@tonic-gate (kl->left)->right = k; 3597c478bd9Sstevel@tonic-gate k->left = kl->left; 360*e2553d68SSerge Dussud free(kl); 361*e2553d68SSerge Dussud } else if ((!(k->notice)->isdummy) && 362*e2553d68SSerge Dussud ((kr->numnote+k->numnote) 363*e2553d68SSerge Dussud <= NLIM)) { 3647c478bd9Sstevel@tonic-gate /* delete this key */ 3657c478bd9Sstevel@tonic-gate (k->notice)->key = NULL; 3667c478bd9Sstevel@tonic-gate kr->numnote += k->numnote; 3677c478bd9Sstevel@tonic-gate (k->left)->right = kr; 3687c478bd9Sstevel@tonic-gate kr->left = k->left; 3697c478bd9Sstevel@tonic-gate free(k); } 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate /* delete n, then advance n down the list */ 3727c478bd9Sstevel@tonic-gate (n->left)->right = n->right; 3737c478bd9Sstevel@tonic-gate (n->right)->left = n->left; 3747c478bd9Sstevel@tonic-gate n2 = n->right; 3757c478bd9Sstevel@tonic-gate free(n); 3767c478bd9Sstevel@tonic-gate n = n2; 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate if (flag) break; 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate /* now reset current */ 3817c478bd9Sstevel@tonic-gate k = (index->key)->left; 3827c478bd9Sstevel@tonic-gate while (k->left != NULL) k = k->left; 3837c478bd9Sstevel@tonic-gate n = (k->notice)->right; 3847c478bd9Sstevel@tonic-gate while ((n != NULL) && (n->isdummy)) n = n->right; 3857c478bd9Sstevel@tonic-gate current = n; 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate 389*e2553d68SSerge Dussud /* ********************* */ 390032624d5Sbasabi int 391032624d5Sbasabi el_empty(void) 392*e2553d68SSerge Dussud /* ********************* */ 3937c478bd9Sstevel@tonic-gate { 394*e2553d68SSerge Dussud if (current == NULL) 395*e2553d68SSerge Dussud return (1); 396*e2553d68SSerge Dussud else 397*e2553d68SSerge Dussud return (0); 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate 401*e2553d68SSerge Dussud /* ********************* */ 4027c478bd9Sstevel@tonic-gate void * 403032624d5Sbasabi el_first(void) 404*e2553d68SSerge Dussud /* ********************* */ 4057c478bd9Sstevel@tonic-gate { 4067c478bd9Sstevel@tonic-gate struct notice *n, *fn; 4077c478bd9Sstevel@tonic-gate struct key *k, *fk; 4087c478bd9Sstevel@tonic-gate struct index *ind, *fi; 4097c478bd9Sstevel@tonic-gate int ctr, *val; 4107c478bd9Sstevel@tonic-gate time_t next_int; 4117c478bd9Sstevel@tonic-gate 412*e2553d68SSerge Dussud if ((index == NULL) || (current == NULL)) 413*e2553d68SSerge Dussud return (NULL); 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate while ((index->key)->time < current->time) { 4167c478bd9Sstevel@tonic-gate if (DU == 2) { 4177c478bd9Sstevel@tonic-gate /* only two intervals, so relabel first one */ 4187c478bd9Sstevel@tonic-gate k = index->key; 4197c478bd9Sstevel@tonic-gate k->time += DT; 4207c478bd9Sstevel@tonic-gate (k->notice)->time += DT; 4217c478bd9Sstevel@tonic-gate continue; } 422*e2553d68SSerge Dussud /* 423*e2553d68SSerge Dussud * remove the notice, key, and index corresponding 424*e2553d68SSerge Dussud * to the first time interval. Then split the 425*e2553d68SSerge Dussud * overflow interval into a normal interval 426*e2553d68SSerge Dussud * plus an overflow interval. 427*e2553d68SSerge Dussud */ 4287c478bd9Sstevel@tonic-gate fi = index; 4297c478bd9Sstevel@tonic-gate fk = fi->key; 4307c478bd9Sstevel@tonic-gate fn = fk->notice; 4317c478bd9Sstevel@tonic-gate (fn->left)->right = fn->right; 4327c478bd9Sstevel@tonic-gate (fn->right)->left = fn->left; 4337c478bd9Sstevel@tonic-gate (fk->left)->right = fk->right; 4347c478bd9Sstevel@tonic-gate (fk->right)->left = fk->left; 4357c478bd9Sstevel@tonic-gate index = index->right; 4367c478bd9Sstevel@tonic-gate /* find where to split */ 4377c478bd9Sstevel@tonic-gate ind = index; 4387c478bd9Sstevel@tonic-gate while ((ind->right)->right != NULL) ind = ind->right; 4397c478bd9Sstevel@tonic-gate /* ind points to the next to last index interval */ 4407c478bd9Sstevel@tonic-gate k = ind->key; 4417c478bd9Sstevel@tonic-gate next_int = k->time + DT; /* upper bound on new inter. */ 4427c478bd9Sstevel@tonic-gate while (k->time < next_int) k = k->right; 4437c478bd9Sstevel@tonic-gate /* k points to the appropriate sublist of notices */ 4447c478bd9Sstevel@tonic-gate n = (k->notice)->left; 4457c478bd9Sstevel@tonic-gate ctr = 1; 4467c478bd9Sstevel@tonic-gate while (n->time >= next_int) { 4477c478bd9Sstevel@tonic-gate ctr++; 4487c478bd9Sstevel@tonic-gate n = n->left; } 4497c478bd9Sstevel@tonic-gate n = n->right; 450*e2553d68SSerge Dussud /* 451*e2553d68SSerge Dussud * n points to first notice of the new overflow interval 452*e2553d68SSerge Dussud * ctr tells how many notices are in the first sublist 453*e2553d68SSerge Dussud * of the new overflow interval 454*e2553d68SSerge Dussud * insert the new index element 455*e2553d68SSerge Dussud */ 4567c478bd9Sstevel@tonic-gate fi->right = ind->right; 4577c478bd9Sstevel@tonic-gate ind->right = fi; 4587c478bd9Sstevel@tonic-gate /* insert the new dummy key */ 4597c478bd9Sstevel@tonic-gate fk->time = next_int; 4607c478bd9Sstevel@tonic-gate fk->numnote = k->numnote - ctr + 1; 4617c478bd9Sstevel@tonic-gate fk->left = k->left; 4627c478bd9Sstevel@tonic-gate fk->right = k; 4637c478bd9Sstevel@tonic-gate (k->left)->right = fk; 4647c478bd9Sstevel@tonic-gate k->left = fk; 4657c478bd9Sstevel@tonic-gate k->numnote = ctr; 4667c478bd9Sstevel@tonic-gate /* insert the new dummy notice */ 4677c478bd9Sstevel@tonic-gate fn->time = next_int; 4687c478bd9Sstevel@tonic-gate fn->left = n->left; 4697c478bd9Sstevel@tonic-gate fn->right = n; 4707c478bd9Sstevel@tonic-gate (n->left)->right = fn; 4717c478bd9Sstevel@tonic-gate n->left = fn; } 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate /* remove the first element of the list */ 4747c478bd9Sstevel@tonic-gate (current->left)->right = current->right; 4757c478bd9Sstevel@tonic-gate (current->right)->left = current->left; 4767c478bd9Sstevel@tonic-gate /* now update the numnote field in the appropriate key */ 4777c478bd9Sstevel@tonic-gate n = current; 4787c478bd9Sstevel@tonic-gate while (n->key == NULL) n = n->right; 4797c478bd9Sstevel@tonic-gate k = n->key; 4807c478bd9Sstevel@tonic-gate k->numnote = k->numnote - 1; 4817c478bd9Sstevel@tonic-gate /* if numnote = 0 then this key must be removed */ 4827c478bd9Sstevel@tonic-gate if (k->numnote == 0) { 4837c478bd9Sstevel@tonic-gate (k->left)->right = k->right; 4847c478bd9Sstevel@tonic-gate (k->right)->left = k->left; 4857c478bd9Sstevel@tonic-gate free(k); } 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate /* now set current to be the head of the list */ 4887c478bd9Sstevel@tonic-gate fn = current->right; 4897c478bd9Sstevel@tonic-gate while ((fn != NULL) && (fn->isdummy)) 4907c478bd9Sstevel@tonic-gate fn = fn->right; 4917c478bd9Sstevel@tonic-gate val = current->event; 4927c478bd9Sstevel@tonic-gate free(current); 4937c478bd9Sstevel@tonic-gate current = fn; 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate return (val); 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate 499*e2553d68SSerge Dussud /* ************** */ 5007c478bd9Sstevel@tonic-gate void 501032624d5Sbasabi el_delete(void) 502*e2553d68SSerge Dussud /* ************** */ 5037c478bd9Sstevel@tonic-gate { 5047c478bd9Sstevel@tonic-gate /* el_delete frees up all the space associated with the event list */ 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate struct index *ind, *ind2; 5077c478bd9Sstevel@tonic-gate struct key *k, *k2; 5087c478bd9Sstevel@tonic-gate struct notice *n, *n2; 5097c478bd9Sstevel@tonic-gate 510*e2553d68SSerge Dussud if (index == NULL) 511*e2553d68SSerge Dussud return; 5127c478bd9Sstevel@tonic-gate ind = index; 5137c478bd9Sstevel@tonic-gate k = ind->key; 5147c478bd9Sstevel@tonic-gate while (k->left != NULL) k = k->left; 5157c478bd9Sstevel@tonic-gate n = k->notice; 5167c478bd9Sstevel@tonic-gate while (n != NULL) { 5177c478bd9Sstevel@tonic-gate n2 = n->right; 5187c478bd9Sstevel@tonic-gate free(n); 5197c478bd9Sstevel@tonic-gate n = n2; } 5207c478bd9Sstevel@tonic-gate while (k != NULL) { 5217c478bd9Sstevel@tonic-gate k2 = k->right; 5227c478bd9Sstevel@tonic-gate free(k); 5237c478bd9Sstevel@tonic-gate k = k2; } 5247c478bd9Sstevel@tonic-gate while (ind != NULL) { 5257c478bd9Sstevel@tonic-gate ind2 = ind->right; 5267c478bd9Sstevel@tonic-gate free(ind); 5277c478bd9Sstevel@tonic-gate ind = ind2; } 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate index = NULL; 5307c478bd9Sstevel@tonic-gate current = NULL; 5317c478bd9Sstevel@tonic-gate } 532