📄 mplex.ccp
字号:
// 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 + -