00001
00002 #ifndef SENDS_SEGDB_HH
00003 #define SENDS_SEGDB_HH
00004
00005 #include "segment.hh"
00006 #include "gmutex.hh"
00007 #include <iosfwd>
00008 #include <vector>
00009 #include <memory>
00010
00011 namespace sends {
00012
00013 class pool_mgr;
00014
00027 class seg_db {
00028 public:
00031 typedef unsigned long seg_index;
00032
00035 typedef unsigned long gps_type;
00036
00039 typedef unsigned long chan_index;
00040
00043 typedef std::vector<segment> seg_vect;
00044
00052 class linkage {
00053 public:
00058 linkage(seg_index nSegs);
00059
00064 seg_index end(void) const;
00065
00073 void insert_before(seg_index inx, seg_index iaft);
00074
00082 void insert_after(seg_index inx, seg_index past);
00083
00090 seg_index next(seg_index inx) const;
00091
00097 bool null(seg_index inx) const;
00098
00105 seg_index prev(seg_index inx) const;
00106
00114 void unlink(seg_index inx);
00115
00116 private:
00117 typedef std::pair<seg_index,seg_index> dll_node;
00118 typedef std::vector<dll_node> dll_vect;
00119 seg_index mEnd;
00120 dll_vect mVect;
00121 };
00122
00128 class qbase {
00129 public:
00134 qbase(seg_index N);
00135
00139 ~qbase(void);
00140
00145 seg_index first(void) const;
00146
00155 void insert(seg_index iseg, seg_index ib4, linkage& l);
00156
00164 void insert_int(seg_index iseg, seg_index ib4, linkage& l);
00165
00170 seg_index last(void) const;
00171
00178 seg_index next(seg_index iseg, const linkage& l) const;
00179
00186 seg_index prev(seg_index iseg, const linkage& l) const;
00187
00191 void read_lock(void) const;
00192
00197 thread::readwritelock& ref_mutex(void) const;
00198
00204 void remove(seg_index iseg, linkage& l);
00205
00209 void unlock(void) const;
00210
00214 void write_lock(void);
00215
00216 private:
00217 seg_index mFirst;
00218 seg_index mLast;
00219 mutable thread::readwritelock mRWMutex;
00220 };
00221
00224 typedef std::vector<qbase> base_vect;
00225
00226 public:
00233 seg_db(seg_index nSeg, seg_index nChan);
00234
00238 ~seg_db(void);
00239
00245 bool chan_valid(chan_index chan) const;
00246
00250 void clear(void);
00251
00257 std::ostream& dump(std::ostream& out) const;
00258
00263 seg_index end(void) const;
00264
00275 seg_index find(chan_index chan, gps_type start, gps_type stop) const;
00276
00284 seg_index first_gt(chan_index chan, gps_type gps) const;
00285
00290 void free(seg_index iseg);
00291
00304 seg_index get_buffer(pool_mgr& pmgr, chan_index chan, double rate,
00305 int len, gps_type start, gps_type stop);
00306
00316 seg_index get_segment(pool_mgr& pmgr, int buf_class);
00317
00327 seg_index getOldest(int buf_class);
00328
00333 void insert(seg_index inx);
00334
00340 bool is_null(seg_index seg) const;
00341
00349 seg_index last_leq(chan_index ichn, gps_type gps) const;
00350
00356 void make_new(seg_index inx);
00357
00363 segment& operator[](seg_index seg);
00364
00370 const segment& operator[](seg_index seg) const;
00371
00382 seg_index reserve(chan_index chan, gps_type start);
00383
00384 private:
00392 seg_index first_gt_int(chan_index chan, gps_type gps) const;
00393
00402 seg_index last_leq_int(chan_index ichn, gps_type gps) const;
00403
00408 void insert_int(chan_index chan, seg_index inx);
00409
00410 private:
00411 seg_index mNSegs;
00412
00413
00414 qbase mAgeQ;
00415 linkage mAgeLinks;
00416
00417
00418 base_vect mChanBase;
00419 linkage mChanLinks;
00420
00421 seg_vect mSegVect;
00422 };
00423
00424
00425 inline
00426 seg_db::linkage::linkage(seg_index N)
00427 : mEnd(N), mVect(N, dll_node(N,N))
00428 {}
00429
00430 inline void
00431 seg_db::linkage::unlink(seg_index inx) {
00432 seg_index ib4 = mVect[inx].first;
00433 seg_index nxt = mVect[inx].second;
00434 if (ib4 != mEnd) mVect[ib4].second = nxt;
00435 if (nxt != mEnd) mVect[nxt].first = ib4;
00436 mVect[inx].first = mEnd;
00437 mVect[inx].second = mEnd;
00438 }
00439
00440 inline void
00441 seg_db::linkage::insert_before(seg_index seg, seg_index iaft) {
00442 seg_index ib4 = mVect[iaft].first;
00443 mVect[seg].first = ib4;
00444 if (ib4 != mEnd) mVect[ib4].second = seg;
00445 mVect[iaft].first = seg;
00446 mVect[seg].second = iaft;
00447 }
00448
00449 inline void
00450 seg_db::linkage::insert_after(seg_index seg, seg_index ib4) {
00451 seg_index iaft = mVect[ib4].second;
00452 mVect[seg].first = ib4;
00453 mVect[ib4].second = seg;
00454 if (iaft != mEnd) mVect[iaft].first = seg;
00455 mVect[seg].second = iaft;
00456 }
00457
00458 inline seg_db::seg_index
00459 seg_db::linkage::next(seg_index inx) const {
00460 return mVect[inx].second;
00461 }
00462
00463 inline bool
00464 seg_db::linkage::null(seg_index N) const {
00465 return N == mEnd;
00466 }
00467
00468 inline seg_db::seg_index
00469 seg_db::linkage::prev(seg_index inx) const {
00470 return mVect[inx].first;
00471 }
00472
00473 inline seg_db::seg_index
00474 seg_db::linkage::end(void) const {
00475 return mEnd;
00476 }
00477
00478 inline
00479 seg_db::qbase::qbase(seg_index N)
00480 : mFirst(N), mLast(N)
00481 {}
00482
00483 inline
00484 seg_db::qbase::~qbase(void) {
00485 }
00486
00487 inline seg_db::seg_index
00488 seg_db::qbase::first(void) const {
00489 return mFirst;
00490 }
00491
00492 inline seg_db::seg_index
00493 seg_db::qbase::last(void) const {
00494 return mLast;
00495 }
00496
00497 inline seg_db::seg_index
00498 seg_db::qbase::next(seg_index iseg, const linkage& l) const {
00499 if (iseg == l.end()) return iseg;
00500 return l.next(iseg);
00501 }
00502
00503 inline seg_db::seg_index
00504 seg_db::qbase::prev(seg_index iseg, const linkage& l) const {
00505 if (iseg == l.end()) return mLast;
00506 return l.prev(iseg);
00507 }
00508
00509 inline thread::readwritelock&
00510 seg_db::qbase::ref_mutex(void) const {
00511 return mRWMutex;
00512 }
00513
00514 inline bool
00515 seg_db::chan_valid(chan_index chan) const {
00516 return chan < mChanBase.size();
00517 }
00518
00519 inline seg_db::seg_index
00520 seg_db::end(void) const {
00521 return mNSegs;
00522 }
00523
00524 inline bool
00525 seg_db::is_null(seg_index inx) const {
00526 return inx == mNSegs;
00527 }
00528
00529 inline segment&
00530 seg_db::operator[](seg_index seg) {
00531 return mSegVect[seg];
00532 }
00533
00534 inline const segment&
00535 seg_db::operator[](seg_index seg) const {
00536 return mSegVect[seg];
00537 }
00538
00539 }
00540
00541 #endif // !defined(SENDS_SEGDB_HH)