Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

webnode.cc

Go to the documentation of this file.
00001 /** @file webnode.cc */
00002 /* 
00003  * Copyright (C) 2002 Laird Breyer
00004  *  
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  * 
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018  * 
00019  * Author:   Laird Breyer (laird@lbreyer.com)
00020  */
00021 
00022 #include "webnode.h"
00023 
00024 // WebNode objects, which are of type MemoryPooled<WebNodeStruct>,
00025 // are allocated by their own memory manager, part of which is declared here
00026 const int MemoryPooled<WebNodeStruct>::BLOCK_SIZE=WEBNODE_MEMPOOL_DELTA;
00027 MemoryPooled<WebNodeStruct> *MemoryPooled<WebNodeStruct>::freelist = NULL;
00028 
00029 // Link objects, which are of type MemPool<LinkStruct>,
00030 // are allocated by their own memory manager
00031 MemPool<LinkStruct> WebNode::global_link_pool;
00032 
00033 // the global_link_pool contains a few static data members
00034 const int MemPool<LinkStruct>::BLOCK_SIZE = LINK_MEMPOOL_DELTA;
00035 MemPoolObject<LinkStruct>* MemPool<LinkStruct>::mempool1 = NULL;
00036 MemPoolObject<LinkStruct>* MemPool<LinkStruct>::mempool2 = NULL;
00037 
00038 
00039 WebNode :: WebNode(uint32 idno) {
00040   data.id = idno;
00041   data.date = 0;
00042   data.num_valid_tolinks = 0;
00043   data.num_leaflinks = 0;
00044   data.num_tolinks = 0;
00045   data.num_fromlinks = 0;
00046   data.tolinks = NULL;
00047   data.fromlinks = NULL;
00048 }
00049 
00050 /// Sets the earliest known date of the WebNode
00051 /**
00052  * This function is designed to be called several times.
00053  * The earliest nonzero date is retained.
00054  */
00055 void WebNode :: SetDate(uint16 adate) {
00056   if( adate > 0 ) {
00057     if( data.date > 0 ) {
00058       data.date = min(data.date,adate);
00059     } else {
00060       data.date = adate;
00061     }
00062   }
00063 }
00064 
00065 /// Inserts a set of tolinks into the WebNode.
00066 /**
00067  * Inserts (or merges) the raw (character ptr) links
00068  * into the webnode's tolinks array.
00069  */
00070 void WebNode :: InsertRawLinks(RawLinkSet *s) {
00071   assert(data.num_valid_tolinks == 0);
00072   assert(data.num_leaflinks == 0);
00073   if(data.num_tolinks > 0) {
00074     for(int j = 0; j < data.num_tolinks; j++) {
00075       s->insert(data.tolinks[j].data.pointer_diff);
00076     }
00077     WebNode::global_link_pool.Deallocate(data.tolinks,data.num_tolinks);
00078     data.num_tolinks = 0;
00079   }
00080 
00081   data.num_tolinks = s->size();
00082   if( data.num_tolinks > 0 ) {
00083     data.tolinks = WebNode::global_link_pool.Allocate(data.num_tolinks);
00084     int k = 0;
00085     for(RawLinkSet::iterator i = s->begin(); i != s->end(); i++) {
00086       data.tolinks[k++].data.pointer_diff = (*i);
00087     }
00088     assert(k == data.num_tolinks);
00089 
00090   } else {
00091 
00092     data.tolinks = NULL;
00093 
00094   }
00095 }
00096 
00097 
00098 /// This appends a webnode to the fromlinks list.
00099 void WebNode :: AppendFromLink(WebNodePtr anothernode) throw (overflow_error) {
00100 
00101   assert(anothernode);
00102   if( data.num_fromlinks <= 0 ) { 
00103     cerr << "error: trying to append to empty fromlink" << endl;
00104     throw overflow_error("");
00105   }
00106 
00107   if( data.fromlinks == NULL ) {
00108     data.fromlinks = WebNode::global_link_pool.Allocate(data.num_fromlinks);
00109     assert(data.fromlinks != NULL);
00110     for(int k = 0; k < data.num_fromlinks; k++) {
00111       data.fromlinks[k].data.webnode_ptr = NULL;
00112     }
00113   }
00114 
00115 
00116   // insert anothernode in the first free nonempty slot. 
00117   for(int k = 0; k < data.num_fromlinks; k++) {
00118     if(data.fromlinks[k].data.webnode_ptr == NULL) {
00119       data.fromlinks[k].data.webnode_ptr = anothernode;
00120       return;
00121     }
00122   }
00123   // if we get to here, there's a problem
00124   cerr << "error: fromlink overflow" << endl;
00125   throw overflow_error("");
00126 }
00127 
00128 /// Sorts all valid links into the first part of the tolinks array.
00129 /**
00130  * While sorting, it also
00131  *  converts the pointer_differences into webnode_ptrs.
00132  * Dangling links are left in the upper half of the array.
00133  *
00134  * Note second argument should really be a data member of first
00135  * (more elegant) but then we'd have to create a derived simplehashtable...
00136  */
00137 void WebNode :: NormalizeRawLinks(SimpleHashTable<WebNodePtr> *h) {
00138   int i, j;
00139   for(i = 0; i < data.num_tolinks; i++) {
00140     WebNodePtr w = h->Find(data.tolinks[i].data.pointer_diff);
00141     if( w ) {
00142       data.tolinks[i].data.webnode_ptr = w;
00143     } else { // its dangling link
00144      // see if another valid link exists
00145       for(j = i + 1; j < data.num_tolinks; j++) {
00146         WebNodePtr v = h->Find(data.tolinks[j].data.pointer_diff);
00147         if( v ) { // found one, swap
00148           data.tolinks[j].data.pointer_diff = data.tolinks[i].data.pointer_diff;
00149           data.tolinks[i].data.webnode_ptr = v;
00150           break;
00151         }
00152       }
00153       if( j == data.num_tolinks ) { // all other links were dangling
00154         // so all elements i, i+1, i+2,... are dangling links
00155         break;
00156       }
00157     }
00158   }
00159 
00160   data.num_valid_tolinks = i;
00161 
00162 #ifndef NDEBUG
00163   // consistency check/validation
00164   for(int k = 0; k < NumberOfValidToLinks(); k++) {
00165     assert(ValidToLink(k));
00166     assert(ValidToLink(k)->OccupationCount() == 0);
00167   }
00168   for(int k = NumberOfValidToLinks(); k < data.num_tolinks; k++) {
00169     assert(!h->Find(data.tolinks[k].data.pointer_diff));
00170   }
00171 #endif
00172 }
00173 
00174 /// Returns the full size of the WebNode including link arrays.
00175 size_t WebNode :: RealSize() {
00176   return sizeof(WebNode) + sizeof(Link) * data.num_tolinks 
00177     + sizeof(Link) * data.num_fromlinks;
00178 }
00179 
00180 
00181 /// sifts LeafNode pointers upward in the tolinks array.
00182 /**
00183  * The code for this function is very similar to that of NormalizeRawLinks()
00184  */
00185 void WebNode :: UpdateLeafLinks(SimpleLeafNodePtrHashTable *leaftable) {
00186   int i, j;
00187   for(i = data.num_valid_tolinks + data.num_leaflinks; i < data.num_tolinks; i++) {
00188     LeafNodePtr w = leaftable->Find(data.tolinks[i].data.pointer_diff);
00189     if( w ) {
00190       data.tolinks[i].data.leafnode_ptr = w;
00191     } else { // its dangling link
00192      // see if another leafnode link exists
00193       for(j = i + 1; j < data.num_tolinks; j++) {
00194         LeafNodePtr v = leaftable->Find(data.tolinks[j].data.pointer_diff);
00195         if( v ) { // found one, swap
00196           data.tolinks[j].data.pointer_diff = data.tolinks[i].data.pointer_diff;
00197           data.tolinks[i].data.leafnode_ptr = v;
00198           break;
00199         }
00200       }
00201       if( j == data.num_tolinks ) { // all other links were dangling
00202         // so all elements i, i+1, i+2,... are dangling links
00203         break;
00204       }
00205     }
00206   }
00207 
00208   data.num_leaflinks = i - data.num_valid_tolinks;
00209 
00210 #ifndef NDEBUG
00211   // consistency check/validation
00212   for(int k = 0; k < NumberOfLeafLinks(); k++) {
00213     assert(ValidLeafLink(k));
00214     assert(ValidLeafLink(k)->OccupationCount() == 0);
00215   }
00216   for(int k = NumberOfValidToLinks() + NumberOfLeafLinks(); k < data.num_tolinks; k++) {
00217     assert(!leaftable->Find(data.tolinks[k].data.pointer_diff));
00218   }
00219 #endif
00220   
00221 }

Generated on Wed May 29 11:37:16 2002 for MarkovPR by doxygen1.2.15