magic/mzrouter/mzNumLine.c

269 lines
5.7 KiB
C

/*
* mzNumberLine.c --
*
* Implements datastructure that permits division of line into intervals
* (end points) are integers, and given any interger, allows (quick) access to
* the interval containing that integer.
*
* *********************************************************************
* * Copyright (C) 1988, 1990 Michael H. Arnold and the Regents of the *
* * University of California. *
* * Permission to use, copy, modify, and distribute this *
* * software and its documentation for any purpose and without *
* * fee is hereby granted, provided that the above copyright *
* * notice appear in all copies. The University of California *
* * makes no representations about the suitability of this *
* * software for any purpose. It is provided "as is" without *
* * express or implied warranty. Export of this software outside *
* * of the United States of America may require an export license. *
* *********************************************************************
*/
#ifndef lint
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/mzrouter/mzNumLine.c,v 1.2 2010/10/22 15:02:15 tim Exp $";
#endif /* not lint */
/* -- includes -- */
#include <stdio.h>
#include "utils/magic.h"
#include "utils/geometry.h"
#include "utils/geofast.h"
#include "tiles/tile.h"
#include "utils/hash.h"
#include "database/database.h"
#include "utils/signals.h"
#include "textio/textio.h"
#include "windows/windows.h"
#include "dbwind/dbwind.h"
#include "utils/malloc.h"
#include "utils/list.h"
#include "debug/debug.h"
#include "textio/textio.h"
#include "utils/heap.h"
#include "mzrouter/mzrouter.h"
#include "mzrouter/mzInternal.h"
/*
* ----------------------------------------------------------------------------
*
* mzNLInit -
*
* Initial a number line.
*
* Results:
* None.
*
* Side effects:
* Allocs entires array and sets number line to the single interval
* from MINFINITY to INFINITY.
*
* ----------------------------------------------------------------------------
*/
void
mzNLInit(nL, size)
NumberLine *nL;
int size; /*initial size of number line */
{
int *entries;
size = MAX(size, 2);
nL->nl_sizeAlloced = size;
nL->nl_sizeUsed = 2;
entries = (int *) mallocMagic((unsigned)(sizeof(int)*size));
entries[0] = MINFINITY;
entries[1] = INFINITY;
nL->nl_entries = entries;
return;
}
/*
* ----------------------------------------------------------------------------
*
* mzNLInsert -
*
* Add new division point to numberline.
*
* Results:
* None.
*
* Side effects:
* Modifiy number line, allocate larger entry array if necessary.
*
* ----------------------------------------------------------------------------
*/
void
mzNLInsert(nL,x)
NumberLine *nL;
int x; /* new point */
{
int lowI, highI;
/* find entries bounding x */
{
lowI = 0;
highI = nL->nl_sizeUsed - 1;
while(highI-lowI > 1)
{
int newI = lowI + (highI - lowI)/2;
int newV = nL->nl_entries[newI];
if(newV <= x)
{
lowI = newI;
}
if(newV >= x)
{
highI = newI;
}
}
}
/* if x is already an entry, just return */
if(lowI == highI)
{
return;
}
/* if number line is full, allocate twice as big an entry array */
if(nL->nl_sizeUsed == nL->nl_sizeAlloced)
{
int *newEntries;
int newSize;
/* allocate new entry array */
newSize = nL->nl_sizeUsed*2;
newEntries = (int *) mallocMagic(sizeof(int) * (unsigned)(newSize));
/* copy old entries to new */
{
int *sentinel = &(nL->nl_entries[nL->nl_sizeAlloced]);
int *source = nL->nl_entries;
int *target = newEntries;
while(source != sentinel)
{
*(target++) = *(source++);
}
}
/* free up old array */
freeMagic(nL->nl_entries);
/* update numberline */
nL->nl_sizeAlloced = newSize;
nL->nl_entries = newEntries;
}
/* move larger entries down one to make room */
{
int * sentinel = &((nL->nl_entries)[lowI]);
int * target = &((nL->nl_entries)[nL->nl_sizeUsed]);
int * source = target-1;
while(source!=sentinel)
{
*(target--) = *(source--);
}
}
/* insert new entry */
(nL->nl_entries)[highI] = x;
/* update entry count */
(nL->nl_sizeUsed)++;
/* and return */
return;
}
/*
* ----------------------------------------------------------------------------
*
* mzNLGetContainingInterval -
*
* Find interval containing x (by binary search)
*
* Results:
* Pointer to array of two ints bounding x.
*
* Side effects:
* None.
*
* ----------------------------------------------------------------------------
*/
int *
mzNLGetContainingInterval(nL,x)
NumberLine *nL;
int x; /* new point */
{
int lowI, highI;
/* find entries bounding x */
{
lowI = 0;
highI = nL->nl_sizeUsed - 1;
while(highI-lowI > 1)
{
int newI = lowI + (highI - lowI)/2;
int newV = nL->nl_entries[newI];
if(newV <= x)
{
lowI = newI;
}
if(newV >= x)
{
highI = newI;
}
}
}
/* return pointer to bounding entries */
return &((nL->nl_entries)[lowI]);
}
/*
* ----------------------------------------------------------------------------
*
* mzNLClear -
*
* Clears numberline to single interval from MINFINITY to INFINITY.
*
* Results:
* None.
*
* Side effects:
* See above. CURRENTLY WE LEAVE THE ALLOCATED SIZE OF THE NUMBERLINE
* ALONE.
*
* ----------------------------------------------------------------------------
*/
void
mzNLClear(nL)
NumberLine *nL;
{
nL->nl_entries[0] = MINFINITY;
nL->nl_entries[1] = INFINITY;
nL->nl_sizeUsed = 2;
return;
}