## modules/up/src/rpsl/gnu/PrefixRange.XPlex.cc

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. PrefixRangeXPlex
2. PrefixRangeXPlex
3. PrefixRangeXPlex
4. make_initial_chunks
5. PrefixRangeXPlex
6. PrefixRangeXPlex
7. cache
8. cache
9. owns
10. dosucc
11. dopred
12. add_high
13. del_high
14. add_low
15. del_low
16. reverse
17. fill
18. fill
19. clear
20. OK

       1 // This may look like C code, but it is really -*- C++ -*-
       2 /*
       3 Copyright (C) 1988 Free Software Foundation
       4     written by Doug Lea (dl@rocky.oswego.edu)
       5     based on code by Marc Shapiro (shapiro@sor.inria.fr)
       6
       7 This file is part of the GNU C++ Library.  This library is free
       8 software; you can redistribute it and/or modify it under the terms of
       9 the GNU Library General Public License as published by the Free
      10 Software Foundation; either version 2 of the License, or (at your
      11 option) any later version.  This library is distributed in the hope
      12 that it will be useful, but WITHOUT ANY WARRANTY; without even the
      13 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
      14 PURPOSE.  See the GNU Library General Public License for more details.
      15 You should have received a copy of the GNU Library General Public
      16 License along with this library; if not, write to the Free Software
      17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
      18 */
      19
      20 #ifdef __GNUG__
      21 #pragma implementation
      22 #endif
      23 #include "PrefixRange.XPlex.h"
      24
      25
      26 PrefixRangeXPlex:: PrefixRangeXPlex()
         /* [<][>][^][v][top][bottom][index][help] */
      27 {
      28   lo = fnc = 0;
      29   csize = DEFAULT_INITIAL_CAPACITY;
      30   PrefixRange* data = new PrefixRange[csize];
      31   set_cache(new PrefixRangeIChunk(data,  lo, lo, fnc, lo+csize));
      32   hd = ch;
      33 }
      34
      35 PrefixRangeXPlex:: PrefixRangeXPlex(int chunksize)
         /* [<][>][^][v][top][bottom][index][help] */
      36 {
      37   if (chunksize == 0) error("invalid constructor specification");
      38   lo = fnc = 0;
      39   if (chunksize > 0)
      40   {
      41     csize = chunksize;
      42     PrefixRange* data = new PrefixRange[csize];
      43     set_cache(new PrefixRangeIChunk(data,  lo, lo, fnc, csize));
      44     hd = ch;
      45   }
      46   else
      47   {
      48     csize = -chunksize;
      49     PrefixRange* data = new PrefixRange[csize];
      50     set_cache(new PrefixRangeIChunk(data,  chunksize, lo, fnc, fnc));
      51     hd = ch;
      52   }
      53 }
      54
      55
      56 PrefixRangeXPlex:: PrefixRangeXPlex(int l, int chunksize)
         /* [<][>][^][v][top][bottom][index][help] */
      57 {
      58   if (chunksize == 0) error("invalid constructor specification");
      59   lo = fnc = l;
      60   if (chunksize > 0)
      61   {
      62     csize = chunksize;
      63     PrefixRange* data = new PrefixRange[csize];
      64     set_cache(new PrefixRangeIChunk(data,  lo, lo, fnc, csize+lo));
      65     hd = ch;
      66   }
      67   else
      68   {
      69     csize = -chunksize;
      70     PrefixRange* data = new PrefixRange[csize];
      71     set_cache(new PrefixRangeIChunk(data,  chunksize+lo, lo, fnc, fnc));
      72     hd = ch;
      73   }
      74 }
      75
      76 void PrefixRangeXPlex::make_initial_chunks(int up)
         /* [<][>][^][v][top][bottom][index][help] */
      77 {
      78   int need = fnc - lo;
      79   hd = 0;
      80   if (up)
      81   {
      82     int l = lo;
      83     do
      84     {
      85       int sz;
      86       if (need >= csize)
      87         sz = csize;
      88       else
      89         sz = need;
      90       PrefixRange* data = new PrefixRange [csize];
      91       PrefixRangeIChunk* h = new PrefixRangeIChunk(data,  l, l, l+sz, l+csize);
      92       if (hd != 0)
      93         h->link_to_next(hd);
      94       else
      95         hd = h;
      96       l += sz;
      97       need -= sz;
      98     } while (need > 0);
      99   }
     100   else
     101   {
     102     int hi = fnc;
     103     do
     104     {
     105       int sz;
     106       if (need >= csize)
     107         sz = csize;
     108       else
     109         sz = need;
     110       PrefixRange* data = new PrefixRange [csize];
     111       PrefixRangeIChunk* h = new PrefixRangeIChunk(data,  hi-csize, hi-sz, hi, hi);
     112       if (hd != 0)
     113         h->link_to_next(hd);
     114       hd = h;
     115       hi -= sz;
     116       need -= sz;
     117     } while (need > 0);
     118   }
     119   set_cache(hd);
     120 }
     121
     122 PrefixRangeXPlex:: PrefixRangeXPlex(int l, int hi, const PrefixRange& initval, int chunksize)
         /* [<][>][^][v][top][bottom][index][help] */
     123 {
     124   lo = l;
     125   fnc = hi + 1;
     126   if (chunksize == 0)
     127   {
     128     csize = fnc - l;
     129     make_initial_chunks(1);
     130   }
     131   else if (chunksize < 0)
     132   {
     133     csize = -chunksize;
     134     make_initial_chunks(0);
     135   }
     136   else
     137   {
     138     csize = chunksize;
     139     make_initial_chunks(1);
     140   }
     141   fill(initval);
     142 }
     143
     144 PrefixRangeXPlex::PrefixRangeXPlex(const PrefixRangeXPlex& a)
         /* [<][>][^][v][top][bottom][index][help] */
     145 {
     146   lo = a.lo;
     147   fnc = a.fnc;
     148   csize = a.csize;
     149   make_initial_chunks();
     150   for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i];
     151 }
     152
     153 void PrefixRangeXPlex::operator= (const PrefixRangeXPlex& a)
     154 {
     155   if (&a != this)
     156   {
     157     invalidate();
     158     lo = a.lo;
     159     fnc = a.fnc;
     160     csize = a.csize;
     161     make_initial_chunks();
     162     for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i];
     163   }
     164 }
     165
     166
     167 void PrefixRangeXPlex::cache(int idx) const
         /* [<][>][^][v][top][bottom][index][help] */
     168 {
     169   const PrefixRangeIChunk* tail = tl();
     170   const PrefixRangeIChunk* t = ch;
     171   while (idx >= t->fence_index())
     172   {
     173     if (t == tail) index_error();
     174     t = (t->next());
     175   }
     176   while (idx < t->low_index())
     177   {
     178     if (t == hd) index_error();
     179     t = (t->prev());
     180   }
     181   set_cache(t);
     182 }
     183
     184
     185 void PrefixRangeXPlex::cache(const PrefixRange* p) const
         /* [<][>][^][v][top][bottom][index][help] */
     186 {
     187   const PrefixRangeIChunk* old = ch;
     188   const PrefixRangeIChunk* t = ch;
     189   while (!t->actual_pointer(p))
     190   {
     191     t = (t->next());
     192     if (t == old) index_error();
     193   }
     194   set_cache(t);
     195 }
     196
     197 int PrefixRangeXPlex::owns(Pix px) const
         /* [<][>][^][v][top][bottom][index][help] */
     198 {
     199   PrefixRange* p = (PrefixRange*)px;
     200   const PrefixRangeIChunk* old = ch;
     201   const PrefixRangeIChunk* t = ch;
     202   while (!t->actual_pointer(p))
     203   {
     204     t = (t->next());
     205     if (t == old) { set_cache(t); return 0; }
     206   }
     207   set_cache(t);
     208   return 1;
     209 }
     210
     211
     212 PrefixRange* PrefixRangeXPlex::dosucc(const PrefixRange* p) const
         /* [<][>][^][v][top][bottom][index][help] */
     213 {
     214   if (p == 0) return 0;
     215   const PrefixRangeIChunk* old = ch;
     216   const PrefixRangeIChunk* t = ch;
     217
     218   while (!t->actual_pointer(p))
     219   {
     220     t = (t->next());
     221     if (t == old)  return 0;
     222   }
     223   int i = t->index_of(p) + 1;
     224   if (i >= fnc) return 0;
     225   if (i >= t->fence_index()) t = (t->next());
     226   set_cache(t);
     227   return (t->pointer_to(i));
     228 }
     229
     230 PrefixRange* PrefixRangeXPlex::dopred(const PrefixRange* p) const
         /* [<][>][^][v][top][bottom][index][help] */
     231 {
     232   if (p == 0) return 0;
     233   const PrefixRangeIChunk* old = ch;
     234   const PrefixRangeIChunk* t = ch;
     235   while (!t->actual_pointer(p))
     236   {
     237     t = (t->prev());
     238     if (t == old) return 0;
     239   }
     240   int i = t->index_of(p) - 1;
     241   if (i < lo) return 0;
     242   if (i < t->low_index()) t = (t->prev());
     243   set_cache(t);
     244   return (t->pointer_to(i));
     245 }
     246
     247
     248 int PrefixRangeXPlex::add_high(const PrefixRange& elem)
         /* [<][>][^][v][top][bottom][index][help] */
     249 {
     250   PrefixRangeIChunk* t = tl();
     251   if (!t->can_grow_high())
     252   {
     253     if (t->PrefixRangeIChunk::empty() && one_chunk())
     254       t->clear(fnc);
     255     else
     256     {
     257       PrefixRange* data = new PrefixRange [csize];
     258       t = (new PrefixRangeIChunk(data,  fnc, fnc, fnc,fnc+csize));
     259       t->link_to_prev(tl());
     260     }
     261   }
     262   *((t->PrefixRangeIChunk::grow_high())) = elem;
     263   set_cache(t);
     264   return fnc++;
     265 }
     266
     267 int PrefixRangeXPlex::del_high ()
         /* [<][>][^][v][top][bottom][index][help] */
     268 {
     269   if (empty()) empty_error();
     270   PrefixRangeIChunk* t = tl();
     271   t->PrefixRangeIChunk::shrink_high();
     272   if (t->PrefixRangeIChunk::empty() && !one_chunk())
     273   {
     274     PrefixRangeIChunk* pred = t->prev();
     275     del_chunk(t);
     276     t = pred;
     277   }
     278   set_cache(t);
     279   return --fnc - 1;
     280 }
     281
     282 int PrefixRangeXPlex::add_low (const PrefixRange& elem)
         /* [<][>][^][v][top][bottom][index][help] */
     283 {
     284   PrefixRangeIChunk* t = hd;
     285   if (!t->can_grow_low())
     286   {
     287     if (t->PrefixRangeIChunk::empty() && one_chunk())
     288       t->cleardown(lo);
     289     else
     290     {
     291       PrefixRange* data = new PrefixRange [csize];
     292       hd = new PrefixRangeIChunk(data,  lo-csize, lo, lo, lo);
     293       hd->link_to_next(t);
     294       t = hd;
     295     }
     296   }
     297   *((t->PrefixRangeIChunk::grow_low())) = elem;
     298   set_cache(t);
     299   return --lo;
     300 }
     301
     302
     303 int PrefixRangeXPlex::del_low ()
         /* [<][>][^][v][top][bottom][index][help] */
     304 {
     305   if (empty()) empty_error();
     306   PrefixRangeIChunk* t = hd;
     307   t->PrefixRangeIChunk::shrink_low();
     308   if (t->PrefixRangeIChunk::empty() && !one_chunk())
     309   {
     310     hd = t->next();
     311     del_chunk(t);
     312     t = hd;
     313   }
     314   set_cache(t);
     315   return ++lo;
     316 }
     317
     318 void PrefixRangeXPlex::reverse()
         /* [<][>][^][v][top][bottom][index][help] */
     319 {
     320   PrefixRange tmp;
     321   int l = lo;
     322   int h = fnc - 1;
     323   PrefixRangeIChunk* loch = hd;
     324   PrefixRangeIChunk* hich = tl();
     325   while (l < h)
     326   {
     327     PrefixRange* lptr = loch->pointer_to(l);
     328     PrefixRange* hptr = hich->pointer_to(h);
     329     tmp = *lptr;
     330     *lptr = *hptr;
     331     *hptr = tmp;
     332     if (++l >= loch->fence_index()) loch = loch->next();
     333     if (--h < hich->low_index()) hich = hich->prev();
     334   }
     335 }
     336
     337 void PrefixRangeXPlex::fill(const PrefixRange& x)
         /* [<][>][^][v][top][bottom][index][help] */
     338 {
     339   for (int i = lo; i < fnc; ++i) (*this)[i] = x;
     340 }
     341
     342 void PrefixRangeXPlex::fill(const PrefixRange& x, int l, int hi)
         /* [<][>][^][v][top][bottom][index][help] */
     343 {
     344   for (int i = l; i <= hi; ++i) (*this)[i] = x;
     345 }
     346
     347
     348 void PrefixRangeXPlex::clear()
         /* [<][>][^][v][top][bottom][index][help] */
     349 {
     350   if (fnc != lo)
     351   {
     352     PrefixRangeIChunk* t = tl();
     353     while (t != hd)
     354     {
     355       PrefixRangeIChunk* prv = t->prev();
     356       del_chunk(t);
     357       t = prv;
     358     }
     359     t->PrefixRangeIChunk::clear(lo);
     360     set_cache(t);
     361     fnc = lo;
     362   }
     363 }
     364
     365
     366 int PrefixRangeXPlex::OK () const
         /* [<][>][^][v][top][bottom][index][help] */
     367 {
     368   int v = hd != 0 && ch != 0;     // at least one chunk
     369
     370   v &= fnc == tl()->fence_index();// last chunk fence == plex fence
     371   v &= lo == ((hd))->PrefixRangeIChunk::low_index();    // first lo == plex lo
     372
     373 // loop for others:
     374   int found_ch = 0;                   // to make sure ch is in list;
     375   const PrefixRangeIChunk* t = (hd);
     376   for (;;)
     377   {
     378     if (t == ch) ++found_ch;
     379     v &= t->PrefixRangeIChunk::OK();              // each chunk is OK
     380     if (t == tl())
     381       break;
     382     else                              // and has indices contiguous to succ
     383     {
     384       v &= t->top_index() == t->next()->base_index();
     385       if (t != hd)                  // internal chunks full
     386       {
     387         v &= !t->empty();
     388         v &= !t->can_grow_low();
     389         v &= !t->can_grow_high();
     390       }
     391       t = t->next();
     392     }
     393   }
     394   v &= found_ch == 1;
     395   if (!v) error("invariant failure");
     396   return v;
     397 }

/* [<][>][^][v][top][bottom][index][help] */