⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mplex.ccp

📁 早期freebsd实现
💻 CCP
📖 第 1 页 / 共 2 页
字号:
// This may look like C code, but it is really -*- C++ -*-/* Copyright (C) 1988 Free Software Foundation    written by Doug Lea (dl@rocky.oswego.edu)    based on code by Marc Shapiro (shapiro@sor.inria.fr)This file is part of the GNU C++ Library.  This library is freesoftware; you can redistribute it and/or modify it under the terms ofthe GNU Library General Public License as published by the FreeSoftware Foundation; either version 2 of the License, or (at youroption) any later version.  This library is distributed in the hopethat it will be useful, but WITHOUT ANY WARRANTY; without even theimplied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULARPURPOSE.  See the GNU Library General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.*/#ifdef __GNUG__#pragma implementation#endif#include "<T>.MPlex.h"// <T>MChunk support<T>MChunk::<T>MChunk(<T>*    d,                     int      baseidx,               int      lowidx,                int      fenceidx,               int      topidx)     : <T>IChunk(d, baseidx, lowidx, fenceidx, topidx){  unused = fence - low;  unsigned msize = (top - base)/_MAP_BITS + 1;  map = (unsigned long *) (new long[msize]);  memset((void*)map, 0, msize * sizeof(long));}void <T>MChunk:: shrink_high (){  if (fence <= low) empty_error();  --fence;  if (!valid(fence))     --unused;  else    free(fence);  reset_high();}void <T>MChunk:: shrink_low (){  if (fence <= low) empty_error();  if (!valid(low))     --unused;  else    free(low);  ++low;  reset_low();}void <T>MChunk::clear(int lo){  int s = top - base;  low = base = fence = lo;  top = base + s;  unused = 0;  bzero((void*)map, ((top - base)/_MAP_BITS + 1) * sizeof(long));}void <T>MChunk::cleardown(int hi){  int s = top - base;  low = top = fence = hi;  base = top - s;  unused = 0;  bzero((void*)map, ((top - base)/_MAP_BITS + 1) * sizeof(long));}int <T>MChunk::del(int idx){  if (idx < low || idx >= fence) index_error();  int v = valid(idx);  if (v)  {    free(idx);    ++unused;  }  return v;}int <T>MChunk::undel(int idx){  if (idx < low || idx >= fence) index_error();  int v = valid(idx);  if (!v)  {    mark(idx);    --unused;  }  return v;}int <T>MChunk::unused_index() const{  if (unused_indices() == 0) index_error();  int slot;  if (low == base)              // can traverse 32 slots at a time  {    int blk = 0;    while (map[blk] == ~0L) ++blk;    slot = blk * _MAP_BITS + base;  }  else    slot = low;  while(valid(slot)) ++slot;  return slot;}int <T>MChunk::first_index() const{  if (empty()) return fence;  int slot;  if (low == base)  {    int blk = 0;    while (map[blk] == 0) ++blk;    slot = blk * _MAP_BITS + base;  }  else    slot = low;  while(!valid(slot)) ++slot;  return slot;}int <T>MChunk::last_index() const{  if (empty()) return low - 1;  int slot;  if (top == fence)  {    int blk = (top - base) / _MAP_BITS;    while (map[blk] == 0) --blk;    slot = blk * _MAP_BITS + base + _MAP_BITS - 1;  }  else    slot = fence - 1;  while(!valid(slot)) --slot;  return slot;}int <T>MChunk:: OK() const{  int v = data != 0;             // have some data  v &= map != 0;                 // and a map  v &= base <= low;              // ok, index-wise  v &= low <= fence;  v &= fence <= top;  v &=  ((<T>MChunk*)(nxt->prev())) == this;      // and links are OK  v &=  ((<T>MChunk*)(prv->next())) == this;  int bitcount = 0;              // and unused count correct  for (int i = low; i < fence; ++i) if (!valid(i)) ++bitcount;  v &= unused == bitcount;    if (!v) error("invariant failure");  return(v);}<T>* <T>MChunk::succ(<T>* p) const{  int i = ((int) p - (int) data) / sizeof(<T>) + base + 1;  if (p == 0 || i < low) return 0;  while (i < fence && !valid(i)) ++i;  if (i >= fence) return 0;  return pointer_to(i);}<T>* <T>MChunk::pred(<T>* p) const{  int i = ((int) p - (int) data) / sizeof(<T>) + base - 1;  if (p == 0 || i >= fence) return 0;  while (i >= low && !valid(i)) --i;  if (i < low) return 0;  return pointer_to(i);}<T>* <T>MChunk::first_pointer() const{  if (empty()) return 0;  int slot;  if (low == base)  {    int blk = 0;    while (map[blk] == 0) ++blk;    slot = blk * _MAP_BITS + base;  }  else    slot = low;  while(!valid(slot)) ++slot;  return pointer_to(slot);}<T>* <T>MChunk::last_pointer() const{  if (empty()) return 0;  int slot;  if (top == fence)  {    int blk = (top - base) / _MAP_BITS;    while (map[blk] == 0) --blk;    slot = blk * _MAP_BITS + base + _MAP_BITS - 1;  }  else    slot = fence - 1;  while(!valid(slot)) --slot;  return pointer_to(slot);}<T>MPlex:: <T>MPlex(){  unused = 0;  lo = fnc = 0;  csize = DEFAULT_INITIAL_CAPACITY;  <T>* data = new <T>[csize];  hd = ch = new <T>MChunk(data,  lo, lo, fnc, lo+csize);}<T>MPlex:: <T>MPlex(int chunksize){  if (chunksize == 0) error("invalid constructor specification");  unused = 0;  lo = fnc = 0;  if (chunksize > 0)  {    csize = chunksize;    <T>* data = new <T>[csize];    hd = ch = new <T>MChunk(data,  lo, lo, fnc, csize);  }  else  {    csize = -chunksize;    <T>* data = new <T>[csize];    hd = ch = new <T>MChunk(data,  chunksize, lo, fnc, fnc);  }}<T>MPlex:: <T>MPlex(int l, int chunksize){  if (chunksize == 0) error("invalid constructor specification");  unused = 0;  lo = fnc = l;  if (chunksize > 0)  {    csize = chunksize;    <T>* data = new <T>[csize];    hd = ch = new <T>MChunk(data,  lo, lo, fnc, csize+lo);  }  else  {    csize = -chunksize;    <T>* data = new <T>[csize];    hd = ch = new <T>MChunk(data,  chunksize+lo, lo, fnc, fnc);  }}void <T>MPlex::make_initial_chunks(int up){  int need = fnc - lo;  hd = 0;  if (up)  {    int l = lo;    do    {      int sz;      if (need >= csize)        sz = csize;      else        sz = need;      <T>* data = new <T> [csize];      <T>MChunk* h = new <T>MChunk(data,  l, l, l+sz, l+csize);      if (hd != 0)        h->link_to_next(hd);      else        hd = h;      l += sz;      need -= sz;    } while (need > 0);  }  else  {    int hi = fnc;    do    {      int sz;      if (need >= csize)        sz = csize;      else        sz = need;      <T>* data = new <T> [csize];      <T>MChunk* h = new <T>MChunk(data,  hi-csize, hi-sz, hi, hi);      if (hd != 0)        h->link_to_next(hd);      hd = h;      hi -= sz;      need -= sz;    } while (need > 0);  }  ch = (<T>MChunk*) hd;}<T>MPlex:: <T>MPlex(int l, int hi, const <T&> initval, int chunksize){  lo = l;  fnc = hi + 1;  if (chunksize == 0)  {    csize = fnc - l;    make_initial_chunks(1);  }  else if (chunksize < 0)  {    csize = -chunksize;    make_initial_chunks(0);  }  else  {    csize = chunksize;    make_initial_chunks(1);  }  unused = fnc - lo;  for (int i=lo; i<fnc; ++i)    undel_index(i);  fill(initval);}<T>MPlex::<T>MPlex(const <T>MPlex& a){  lo = a.lo;  fnc = a.fnc;  csize = a.csize;  unused = fnc - lo;  hd = 0;  const <T>IChunk* p = a.hd;  do  {    <T>* data = new <T> [p->size()];    <T>MChunk* h = new <T>MChunk(data,  p->base_index(),                          p->low_index(), p->fence_index(), p->top_index());    if (hd != 0)      h->link_to_next(hd);    else      hd = h;    p = p->next();  } while (p != a.hd);  ch = (<T>MChunk*) hd;  for (int i = a.low(); i < a.fence(); a.next(i))   {    undel_index(i);    (*this)[i] = a[i];  }}void <T>MPlex::operator= (const <T>MPlex& a){  if (&a != this)  {    invalidate();    lo = a.lo;    fnc = a.fnc;    csize = a.csize;    unused = fnc - lo;    hd = 0;    const <T>IChunk* p = a.hd;    do    {      <T>* data = new <T> [p->size()];      <T>MChunk* h = new <T>MChunk(data,  p->base_index(),                                   p->low_index(), p->fence_index(),                                    p->top_index());      if (hd != 0)        h->link_to_next(hd);      else        hd = h;      p = p->next();    } while (p != a.hd);    ch = (<T>MChunk*) hd;    for (int i = a.low(); i < a.fence(); a.next(i))     {      undel_index(i);      (*this)[i] = a[i];    }  }}int <T>MPlex::valid(int idx) const{  const <T>MChunk* tail = (<T>MChunk*)tl();  const <T>MChunk* t = ch;  while (idx >= t->fence_index())  {    if (t == tail)  return 0;     t = ((<T>MChunk*)(t->next()));  }  while (idx < t->low_index())  {    if (t == (<T>MChunk*)(hd)) return 0;     t = ((<T>MChunk*)(t->prev()));  }  set_cache(t);  return t-><T>MChunk::valid_index(idx);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -