src/work/alpar/oldgraph.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000
changeset 822 88226d9fe821
parent 3 272a5677bd6d
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

Some macros and comments has been changed.
alpar@1
     1
// -*-mode: c++; -*-
alpar@1
     2
#ifndef __OLDGRAPH_H_
alpar@1
     3
#define __OLDGRAPH_H_
alpar@1
     4
alpar@1
     5
#include <stdio.h>
alpar@1
     6
alpar@1
     7
//#include <new>
alpar@1
     8
alpar@1
     9
#define INVALID -1
alpar@1
    10
#define FREE_NODE INVALID
alpar@1
    11
alpar@1
    12
#define EDGE_BLOCK_SIZE 100
alpar@1
    13
#define INIT_NODES_SIZE 10
alpar@1
    14
#define INIT_EDGES_BLOCK_MAX 10
alpar@1
    15
alpar@1
    16
#define foreachNode(n,G) for((n)=(G).FirstNode();(n)!=INVALID;(n)=(G).NextNode(n))
alpar@1
    17
#define foreachIn(e,G,n)  for((e)=(G).FirstIn(n) ;(e);(e)=(G).NextIn(e) )
alpar@1
    18
#define foreachOut(e,G,n) for((e)=(G).FirstOut(n);(e);(e)=(G).NextOut(e))
alpar@1
    19
#define foreachEdge(e,G,n) for((e)=(G).FirstEdge(n);(e);(e)=(G).NextEdge((n),(e)))
alpar@1
    20
alpar@1
    21
struct EdgeIndex { int block,index; };
alpar@1
    22
alpar@1
    23
extern EdgeIndex InvalidIndex;
alpar@1
    24
alpar@1
    25
class EdgeCorp;
alpar@1
    26
typedef EdgeCorp *EdgePoint;
alpar@1
    27
alpar@1
    28
class EdgeCorp {
alpar@1
    29
 public:
alpar@1
    30
  int from,to;      //from==INVALID <=> this is a free edge.
alpar@1
    31
  EdgePoint previn,nextin,prevout,nextout;
alpar@1
    32
  EdgeIndex index;
alpar@1
    33
alpar@1
    34
  int From() { return from; }
alpar@1
    35
  int To() { return to; }
alpar@1
    36
  EdgePoint NextIn() { return nextin; }
alpar@1
    37
  EdgePoint NextOut() { return nextout; }
alpar@1
    38
};
alpar@1
    39
alpar@1
    40
inline int From(EdgePoint e) { return e->from; }
alpar@1
    41
inline int To(EdgePoint e) { return e->to; }
alpar@1
    42
inline EdgePoint NextIn(EdgePoint e) { return e->nextin; }
alpar@1
    43
inline EdgePoint NextOut(EdgePoint e) { return e->nextout; }
alpar@1
    44
alpar@1
    45
alpar@1
    46
//////////////////////////////////////////////////////////////////////
alpar@1
    47
//   OLDGRAPH TEMPLATE
alpar@1
    48
//////////////////////////////////////////////////////////////////////
alpar@1
    49
// Copy Constructor should be provided for N
alpar@1
    50
alpar@1
    51
//class Graph;
alpar@1
    52
//class Graph::NodeIterator; //Nem megy. Disznosag!
alpar@1
    53
template <class N, class E> class OldGraph
alpar@1
    54
{
alpar@1
    55
alpar@1
    56
  //  friend class NEGRO::Graph::NodeIterator; //Nem megy. Disznosag!
alpar@1
    57
alpar@1
    58
alpar@1
    59
  class nodes_t;
alpar@1
    60
  friend class OldGraph::nodes_t;
alpar@1
    61
  class edge_block;
alpar@1
    62
  friend class OldGraph::edge_block;
alpar@1
    63
  
alpar@1
    64
  class edge_t : public EdgeCorp {
alpar@1
    65
  public:
alpar@1
    66
    //edge_t *previn,*nextin,*prevout,*nextout;
alpar@1
    67
    union {
alpar@1
    68
      int _align;
alpar@1
    69
      char data[sizeof(E)];
alpar@1
    70
    };
alpar@1
    71
  };
alpar@1
    72
alpar@1
    73
  class nodes_t {
alpar@1
    74
  public:
alpar@1
    75
    union {
alpar@1
    76
      int _align;
alpar@1
    77
      char data[sizeof(N)];
alpar@1
    78
    };
alpar@1
    79
    int indeg,outdeg;           // indeg==FREE_NODE <=> this node is free.
alpar@1
    80
    EdgePoint firstin, firstout;
alpar@1
    81
    int prev,next;
alpar@1
    82
alpar@1
    83
    void Copy(nodes_t &n) 
alpar@1
    84
    {
alpar@1
    85
      indeg = n.indeg; outdeg = n.outdeg;
alpar@1
    86
      firstin = n.firstin; firstout = n.firstout;
alpar@1
    87
      prev = n.prev; next = n.next;
alpar@1
    88
      if(n.indeg!=FREE_NODE) new(data) N(*(N*)(n.data));
alpar@1
    89
      //      if(n.indeg!=FREE_NODE) {
alpar@1
    90
      //	new(data) N;
alpar@1
    91
      //	(*(N*)(data))=(*(N*)(n.data));
alpar@1
    92
      //      }
alpar@1
    93
    }
alpar@1
    94
    
alpar@1
    95
  } *nodes;
alpar@1
    96
  int nodenum, nodes_size;
alpar@1
    97
  int firstnode, freenodes;
alpar@1
    98
  class edge_block {
alpar@1
    99
  public:
alpar@1
   100
    //edge_block *next;
alpar@1
   101
    //    char fields[sizeof(edge_t)*EDGE_BLOCK_SIZE];
alpar@1
   102
    edge_t fields[EDGE_BLOCK_SIZE];    
alpar@1
   103
  } **edges;
alpar@1
   104
  int edge_block_num,edge_block_max;
alpar@1
   105
  EdgePoint freeedges;
alpar@1
   106
alpar@1
   107
  void setup(int nosi = INIT_NODES_SIZE);
alpar@1
   108
  void destroy();
alpar@1
   109
  void inc_nodes_size(int n);
alpar@1
   110
  
alpar@1
   111
 public:
alpar@1
   112
  int NodeNum() {return nodenum;};
alpar@1
   113
  int EdgeNum();
alpar@3
   114
  int MaxNode() const {return nodes_size;};
alpar@3
   115
  int FirstNode() const {return firstnode;};
alpar@3
   116
  int NextNode(int n) const {return nodes[n].next;};
alpar@3
   117
  int PrevNode(int n) const {return nodes[n].prev;};
alpar@3
   118
  N& operator()(int n) const {return *(N*)(nodes[n].data);};
alpar@3
   119
  N& Data      (int n) const {return *(N*)(nodes[n].data);};
alpar@1
   120
  int AddNode();
alpar@3
   121
  void AddNodeBlock(int n) const {for(int i=0;i<n;i++) AddNode();}
alpar@1
   122
  int AddNode(int n);
alpar@1
   123
  void Delete(int n);
alpar@3
   124
  int isaNode(int n) const 
alpar@3
   125
        {return n>=0&&n<nodes_size&&nodes[n].indeg!=FREE_NODE;};
alpar@1
   126
  
alpar@3
   127
  int InDeg(int n) const {return nodes[n].indeg;};
alpar@3
   128
  int OutDeg(int n) const {return nodes[n].outdeg;};
alpar@3
   129
  EdgePoint FirstIn(int n) const {return nodes[n].firstin;};
alpar@3
   130
  EdgePoint FirstOut(int n) const {return nodes[n].firstout;};
alpar@1
   131
alpar@3
   132
  E& operator()(EdgePoint e) const {return *(E*)(((edge_t*)e)->data);};
alpar@3
   133
  E& Data      (EdgePoint e) const {return *(E*)(((edge_t*)e)->data);};
alpar@3
   134
  int From(EdgePoint e) const {return e->from;};
alpar@3
   135
  int To(EdgePoint e) const {return e->to;};
alpar@3
   136
  EdgePoint NextIn(EdgePoint e) const 
alpar@1
   137
    {return e->nextin;};
alpar@3
   138
  EdgePoint NextOut(EdgePoint e)const 
alpar@1
   139
    {return e->nextout;};
alpar@1
   140
  EdgePoint AddEdge(int f, int t);
alpar@1
   141
  void Delete(EdgePoint e);
alpar@1
   142
  EdgePoint Edge(int f,int t);
alpar@1
   143
  //  EdgePoint Edge(E &d)
alpar@1
   144
  //    {return (EdgePoint)(((char*)&d)-(char*)&(((edge_t*)NULL)->data));};
alpar@3
   145
  E& operator()(int f, int t) const {return *(E*)(((edge_t*)Edge(f,t))->data);};
alpar@3
   146
  E& Data(int f, int t) const {return *(E*)(((edge_t*)Edge(f,t))->data);};
alpar@1
   147
  void Delete(int f, int t) {Delete(Edge(f,t));};
alpar@1
   148
  void Reverse(EdgePoint e);
alpar@1
   149
alpar@1
   150
  // Functions for EdgeIndex
alpar@1
   151
  
alpar@3
   152
  EdgePoint Edge(EdgeIndex i) const 
alpar@1
   153
    { return (EdgePoint)(edges[i.block]->fields+i.index);};
alpar@3
   154
  EdgeIndex Index(EdgePoint e) const { return e->index;};
alpar@3
   155
  EdgeIndex Index(int f, int t) const { EdgePoint e; return Edge(f,t)->index; }
alpar@1
   156
  void Delete(EdgeIndex i) { Delete(Edge(i));};
alpar@3
   157
  E& operator()(EdgeIndex i) const 
alpar@1
   158
     {return *(E*)(edges[i.block]->fields[i.index].data);};
alpar@3
   159
  E& Data(EdgeIndex i) const 
alpar@1
   160
     {return *(E*)(edges[i.block]->fields[i.index].data);};
alpar@1
   161
  EdgePoint AddEdge(int f, int t,EdgeIndex in);
alpar@1
   162
  
alpar@1
   163
alpar@1
   164
  
alpar@1
   165
  // Operators for symmetric graphs:
alpar@1
   166
alpar@3
   167
  EdgePoint FirstEdge(int n) const 
alpar@1
   168
    { return (EdgePoint)(FirstIn(n)?FirstIn(n):FirstOut(n));};
alpar@3
   169
  EdgePoint NextEdge(int n,EdgePoint e) const 
alpar@1
   170
    { return From(e)==n?NextOut(e):(NextIn(e)?NextIn(e):FirstOut(n)); };
alpar@3
   171
  int Opposite(EdgePoint e,int n) const 
alpar@1
   172
    { return From(e)+To(e)-n; };
alpar@1
   173
  
alpar@1
   174
  // Initializers, destructors
alpar@1
   175
       
alpar@1
   176
  OldGraph() {setup();};
alpar@1
   177
  OldGraph(int nosi) {setup(nosi);};
alpar@1
   178
  OldGraph(OldGraph<N,E> &H) {setup();operator=(H);};
alpar@1
   179
  ~OldGraph() {destroy();};  
alpar@1
   180
  void Clean(int nosi = INIT_NODES_SIZE) {destroy();setup(nosi);};
alpar@1
   181
  void Clear(int nosi = INIT_NODES_SIZE) {destroy();setup(nosi);};
alpar@1
   182
alpar@1
   183
  void DeleteEdges();
alpar@1
   184
    
alpar@1
   185
  OldGraph<N,E> &operator=(OldGraph<N,E> &H);
alpar@1
   186
};
alpar@1
   187
alpar@1
   188
//////////////////////////////////////////////////////////////////////
alpar@1
   189
// Template Definitions
alpar@1
   190
//////////////////////////////////////////////////////////////////////
alpar@1
   191
alpar@1
   192
//#include <stdio.h>
alpar@1
   193
alpar@1
   194
//**********************************************************************
alpar@1
   195
//                          OldGraph definitions
alpar@1
   196
//**********************************************************************
alpar@1
   197
alpar@1
   198
template<class N, class E> void OldGraph<N,E>::setup(int nosi) {
alpar@1
   199
  int i;
alpar@1
   200
alpar@1
   201
  //Set up nodes
alpar@1
   202
  nodenum = 0;
alpar@1
   203
  nodes_size = nosi;
alpar@1
   204
  // nodes = (nodes_t*) new char[sizeof(nodes_t)*nodes_size];
alpar@1
   205
  nodes = (nodes_t*) new nodes_t [nodes_size];
alpar@1
   206
  for(i=0;i<nodes_size;i++)
alpar@1
   207
    {
alpar@1
   208
      nodes[i].prev=i-1;
alpar@1
   209
      nodes[i].next=i+1;
alpar@1
   210
      nodes[i].indeg=FREE_NODE;
alpar@1
   211
      nodes[i].outdeg=0;
alpar@1
   212
      nodes[i].firstin=nodes[i].firstout=NULL;
alpar@1
   213
    }
alpar@1
   214
  firstnode=nodes[0].prev=nodes[nodes_size-1].next=INVALID;
alpar@1
   215
  freenodes=0;
alpar@1
   216
  //Set up edge-list_template_type;
alpar@1
   217
  freeedges = NULL;
alpar@1
   218
  
alpar@1
   219
  edges = new edge_block* [edge_block_max=INIT_EDGES_BLOCK_MAX];
alpar@1
   220
  edge_block_num = 0;
alpar@1
   221
  
alpar@1
   222
}
alpar@1
   223
alpar@1
   224
template<class N, class E> void OldGraph<N,E>::destroy()
alpar@1
   225
{
alpar@1
   226
  int i;
alpar@1
   227
  
alpar@1
   228
  while(firstnode!=INVALID) Delete(firstnode);
alpar@1
   229
  delete [] nodes;
alpar@1
   230
  for(i=0;i<edge_block_num;i++) delete edges[i];
alpar@1
   231
  delete [] edges;
alpar@1
   232
}
alpar@1
   233
alpar@1
   234
template<class N, class E> void OldGraph<N,E>::inc_nodes_size(int n)
alpar@1
   235
{
alpar@1
   236
  int i;
alpar@1
   237
  if(n<=nodenum) return;
alpar@1
   238
  
alpar@1
   239
  nodes_t *nn;
alpar@1
   240
//  nn = (nodes_t*) new char [sizeof(nodes_t)*n];
alpar@1
   241
  nn = (nodes_t*) new nodes_t [n];
alpar@1
   242
  for(i=0;i<nodes_size;i++)
alpar@1
   243
    {
alpar@1
   244
      nn[i].Copy(nodes[i]);
alpar@1
   245
      if(nodes[i].indeg!=FREE_NODE) ((N*)(nodes[i].data))->~N();
alpar@1
   246
    }
alpar@1
   247
  
alpar@1
   248
  delete [] nodes;
alpar@1
   249
  nodes = nn;
alpar@1
   250
  for(i=nodes_size;i<n;i++)
alpar@1
   251
    {
alpar@1
   252
      nodes[i].prev=i-1;
alpar@1
   253
      nodes[i].next=i+1;
alpar@1
   254
      nodes[i].indeg=FREE_NODE;
alpar@1
   255
      nodes[i].outdeg=0;
alpar@1
   256
      nodes[i].firstin=nodes[i].firstout=NULL;
alpar@1
   257
    }
alpar@1
   258
  nodes[nodes_size].prev=INVALID;
alpar@1
   259
  nodes[n-1].next=freenodes;
alpar@1
   260
  if(freenodes!=INVALID) nodes[freenodes].prev=n-1;
alpar@1
   261
  freenodes=nodes_size;
alpar@1
   262
  nodes_size=n;
alpar@1
   263
}
alpar@1
   264
alpar@1
   265
template<class N, class E> OldGraph<N,E> &OldGraph<N,E>::operator=(OldGraph<N,E> &H)
alpar@1
   266
{
alpar@1
   267
  Clean();
alpar@1
   268
alpar@1
   269
  int i;
alpar@1
   270
  EdgePoint e;
alpar@1
   271
  
alpar@1
   272
  for(i=H.FirstNode();i!=INVALID;i=H.NextNode(i))
alpar@1
   273
    {
alpar@1
   274
      AddNode(i);
alpar@1
   275
      operator()(i)=H(i);
alpar@1
   276
    }
alpar@1
   277
  for(i=H.FirstNode();i!=INVALID;i=H.NextNode(i))
alpar@1
   278
    for(e=H.FirstOut(i);e;e=H.NextOut(e))
alpar@1
   279
      operator()(AddEdge(i,H.To(e),H.Index(e)))=H(e);
alpar@1
   280
alpar@1
   281
   return *this;
alpar@1
   282
}
alpar@1
   283
alpar@1
   284
template<class N, class E> int OldGraph<N,E>::EdgeNum()
alpar@1
   285
{
alpar@1
   286
  int n=firstnode, m=0;
alpar@1
   287
  EdgePoint e;
alpar@1
   288
  while(n != INVALID)
alpar@1
   289
  {    
alpar@1
   290
    e=FirstOut(n);
alpar@1
   291
    while (e != NULL)
alpar@1
   292
    {
alpar@1
   293
      m++;
alpar@1
   294
      e=NextOut(e);
alpar@1
   295
    }
alpar@1
   296
    n=nodes[n].next;
alpar@1
   297
  }
alpar@1
   298
  return m;
alpar@1
   299
}
alpar@1
   300
alpar@1
   301
template<class N, class E> int OldGraph<N,E>::AddNode()
alpar@1
   302
{
alpar@1
   303
  int i;
alpar@1
   304
  
alpar@1
   305
  if(freenodes==INVALID) inc_nodes_size(2*nodes_size);
alpar@1
   306
  
alpar@1
   307
  i=freenodes;
alpar@1
   308
  if(firstnode!=INVALID) nodes[firstnode].prev=i;
alpar@1
   309
  freenodes=nodes[i].next;
alpar@1
   310
  new(nodes[i].data) N;  //Explicit constructor call
alpar@1
   311
  nodes[i].next=firstnode;
alpar@1
   312
  nodes[i].prev=INVALID;
alpar@1
   313
  nodes[i].indeg=0;
alpar@1
   314
  firstnode=i;
alpar@1
   315
  if(freenodes!=INVALID) nodes[freenodes].prev=INVALID;
alpar@1
   316
  nodenum++;
alpar@1
   317
  return i;
alpar@1
   318
}
alpar@1
   319
alpar@1
   320
template<class N, class E> int OldGraph<N,E>::AddNode(int n)
alpar@1
   321
{
alpar@1
   322
  int i;
alpar@1
   323
  
alpar@1
   324
  if(n>=nodes_size)
alpar@1
   325
    {
alpar@1
   326
      for(i=INIT_NODES_SIZE;i<=n;i*=2) ;
alpar@1
   327
      inc_nodes_size(i);
alpar@1
   328
    }
alpar@1
   329
  
alpar@1
   330
  if(nodes[n].indeg==FREE_NODE)
alpar@1
   331
    {
alpar@1
   332
      new(nodes[n].data) N;  //Explicit constructor call
alpar@1
   333
      if(nodes[n].next!=INVALID) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@1
   334
      if(nodes[n].prev!=INVALID) nodes[nodes[n].prev].next = nodes[n].next;
alpar@1
   335
      else freenodes = nodes[n].next;
alpar@1
   336
      
alpar@1
   337
      nodes[n].prev = INVALID;
alpar@1
   338
      if((nodes[n].next = firstnode)!=INVALID) nodes[firstnode].prev=n;
alpar@1
   339
      firstnode = n;
alpar@1
   340
      nodenum++;
alpar@1
   341
      nodes[n].indeg=0;
alpar@1
   342
    }
alpar@1
   343
  return n;
alpar@1
   344
}
alpar@1
   345
alpar@1
   346
template<class N, class E> void OldGraph<N,E>::Delete(int n)
alpar@1
   347
{
alpar@1
   348
  if(n==INVALID||nodes[n].indeg==FREE_NODE) return;
alpar@1
   349
alpar@1
   350
  EdgePoint e;
alpar@1
   351
  
alpar@1
   352
  while(e=FirstIn(n)) Delete(e);
alpar@1
   353
  while(e=FirstOut(n)) Delete(e);
alpar@1
   354
  
alpar@1
   355
  if(n==firstnode) firstnode=nodes[n].next;
alpar@1
   356
  if(nodes[n].prev!=INVALID) nodes[nodes[n].prev].next=nodes[n].next;
alpar@1
   357
  if(nodes[n].next!=INVALID) nodes[nodes[n].next].prev=nodes[n].prev;
alpar@1
   358
  if(freenodes!=INVALID) nodes[freenodes].prev=n;
alpar@1
   359
  nodes[n].next=freenodes;
alpar@1
   360
  nodes[n].prev=INVALID;
alpar@1
   361
  nodes[n].indeg=FREE_NODE;
alpar@1
   362
  ((N*)(nodes[n].data))->~N();  //Explicit destructor call
alpar@1
   363
  freenodes=n;
alpar@1
   364
alpar@1
   365
  nodenum--;
alpar@1
   366
}
alpar@1
   367
alpar@1
   368
template<class N, class E> EdgePoint OldGraph<N,E>::AddEdge(int f, int t)
alpar@1
   369
{
alpar@1
   370
  int i;
alpar@1
   371
  edge_block *peb;
alpar@1
   372
  edge_block **ppeb;
alpar@1
   373
  edge_t *e;
alpar@1
   374
  
alpar@1
   375
  if(!freeedges)
alpar@1
   376
    {
alpar@1
   377
      if(edge_block_num>=edge_block_max)
alpar@1
   378
	{
alpar@1
   379
	  ppeb = new edge_block* [edge_block_max*=2];
alpar@1
   380
	  for(i=0;i<edge_block_num;i++) ppeb[i]=edges[i];
alpar@1
   381
	  delete [] edges;
alpar@1
   382
	  edges = ppeb;
alpar@1
   383
	}
alpar@1
   384
      peb = new edge_block;
alpar@1
   385
      edges[edge_block_num] = peb;
alpar@1
   386
      
alpar@1
   387
      for(i=0;i<EDGE_BLOCK_SIZE;i++)
alpar@1
   388
	{
alpar@1
   389
	  ((edge_t*)peb->fields)[i].nextin=((edge_t*)peb->fields)+(i+1);
alpar@1
   390
	  ((edge_t*)peb->fields)[i].previn=((edge_t*)peb->fields)+(i-1);
alpar@1
   391
	  ((edge_t*)peb->fields)[i].index.block = edge_block_num;
alpar@1
   392
	  ((edge_t*)peb->fields)[i].index.index = i;
alpar@1
   393
	  ((edge_t*)peb->fields)[i].from = INVALID;
alpar@1
   394
	}
alpar@1
   395
      ((edge_t*)peb->fields)[0].previn=
alpar@1
   396
	((edge_t*)peb->fields)[EDGE_BLOCK_SIZE-1].nextin=NULL;
alpar@1
   397
      freeedges = (edge_t*)peb->fields;
alpar@1
   398
      edge_block_num++;
alpar@1
   399
    }
alpar@1
   400
  
alpar@1
   401
  e=(edge_t *)freeedges;
alpar@1
   402
  new (e->data) E;  //Explicit constructor call
alpar@1
   403
  freeedges=e->nextin;
alpar@1
   404
  if(freeedges) freeedges->previn=NULL;
alpar@1
   405
  
alpar@1
   406
  e->from=f; e->to=t;
alpar@1
   407
  e->previn=e->prevout=NULL;
alpar@1
   408
  e->nextin=nodes[t].firstin;
alpar@1
   409
  e->nextout=nodes[f].firstout;
alpar@1
   410
  if(nodes[t].firstin) nodes[t].firstin->previn=e;
alpar@1
   411
  if(nodes[f].firstout) nodes[f].firstout->prevout=e;
alpar@1
   412
  nodes[t].firstin=nodes[f].firstout=e;
alpar@1
   413
  nodes[t].indeg++; nodes[f].outdeg++;
alpar@1
   414
alpar@1
   415
  return (EdgePoint)e;
alpar@1
   416
  
alpar@1
   417
}
alpar@1
   418
alpar@1
   419
template<class N, class E>
alpar@1
   420
EdgePoint OldGraph<N,E>::AddEdge(int f, int t, EdgeIndex in)
alpar@1
   421
{
alpar@1
   422
  int i;
alpar@1
   423
  edge_block *peb;
alpar@1
   424
  edge_block **ppeb;
alpar@1
   425
  edge_t *e;
alpar@1
   426
  
alpar@1
   427
  while(edge_block_num<=in.block)
alpar@1
   428
    {
alpar@1
   429
      if(edge_block_num>=edge_block_max)
alpar@1
   430
	{
alpar@1
   431
	  ppeb = new edge_block* [edge_block_max*=2];
alpar@1
   432
	  for(i=0;i<edge_block_num;i++) ppeb[i]=edges[i];
alpar@1
   433
	  delete [] edges;
alpar@1
   434
	  edges = ppeb;
alpar@1
   435
	}
alpar@1
   436
      peb = new edge_block;
alpar@1
   437
      edges[edge_block_num] = peb;
alpar@1
   438
      
alpar@1
   439
      for(i=0;i<EDGE_BLOCK_SIZE;i++)
alpar@1
   440
	{
alpar@1
   441
	  ((edge_t*)peb->fields)[i].nextin=((edge_t*)peb->fields)+(i+1);
alpar@1
   442
	  ((edge_t*)peb->fields)[i].previn=((edge_t*)peb->fields)+(i-1);
alpar@1
   443
	  ((edge_t*)peb->fields)[i].index.block = edge_block_num;
alpar@1
   444
	  ((edge_t*)peb->fields)[i].index.index = i;
alpar@1
   445
	  ((edge_t*)peb->fields)[i].from = INVALID;
alpar@1
   446
	}
alpar@1
   447
      ((edge_t*)peb->fields)[0].previn=NULL;
alpar@1
   448
      ((edge_t*)peb->fields)[EDGE_BLOCK_SIZE-1].nextin=freeedges;
alpar@1
   449
      if(freeedges)
alpar@1
   450
	freeedges->previn = ((edge_t*)peb->fields) + (EDGE_BLOCK_SIZE-1);
alpar@1
   451
      freeedges = (edge_t*)peb->fields;
alpar@1
   452
      edge_block_num++;
alpar@1
   453
    }
alpar@1
   454
  
alpar@1
   455
  
alpar@1
   456
  e=((edge_t*)(edges[in.block]->fields))+in.index;
alpar@1
   457
  if(e->from==INVALID)
alpar@1
   458
    {
alpar@1
   459
      if(e->previn) e->previn->nextin = e->nextin;
alpar@1
   460
               else freeedges = e->nextin;
alpar@1
   461
      if(e->nextin) e->nextin->previn = e->previn;
alpar@1
   462
alpar@1
   463
      new (e->data) E;  //Explicit constructor call
alpar@1
   464
      
alpar@1
   465
      e->from=f; e->to=t;
alpar@1
   466
      e->previn=e->prevout=NULL;
alpar@1
   467
      e->nextin=nodes[t].firstin;
alpar@1
   468
      e->nextout=nodes[f].firstout;
alpar@1
   469
      if(nodes[t].firstin) nodes[t].firstin->previn=e;
alpar@1
   470
      if(nodes[f].firstout) nodes[f].firstout->prevout=e;
alpar@1
   471
      nodes[t].firstin=nodes[f].firstout=e;
alpar@1
   472
      nodes[t].indeg++; nodes[f].outdeg++;
alpar@1
   473
    }
alpar@1
   474
  return (EdgePoint)e;
alpar@1
   475
}
alpar@1
   476
alpar@1
   477
template<class N, class E> void OldGraph<N,E>::Delete(EdgePoint e)
alpar@1
   478
{
alpar@1
   479
  if(!e||e->from==INVALID) return;
alpar@1
   480
  
alpar@1
   481
  ((E*)(((edge_t*)e)->data))->~E();  //Explicit destructor call
alpar@1
   482
  
alpar@1
   483
  nodes[e->from].outdeg--; nodes[e->to].indeg--;
alpar@1
   484
alpar@1
   485
  
alpar@1
   486
  if(e->previn)
alpar@1
   487
    e->previn->nextin=e->nextin;
alpar@1
   488
  else nodes[e->to].firstin=e->nextin;
alpar@1
   489
  if(e->prevout)
alpar@1
   490
    e->prevout->nextout=e->nextout;
alpar@1
   491
  else nodes[e->from].firstout=e->nextout;
alpar@1
   492
  if(e->nextin)
alpar@1
   493
    e->nextin->previn=e->previn;
alpar@1
   494
  if(e->nextout)
alpar@1
   495
    e->nextout->prevout=e->prevout;
alpar@1
   496
  
alpar@1
   497
  if(freeedges) freeedges->previn=e;
alpar@1
   498
  e->previn=NULL; e->nextin=freeedges;
alpar@1
   499
alpar@1
   500
  e->from = INVALID;
alpar@1
   501
  freeedges=e;
alpar@1
   502
}
alpar@1
   503
alpar@1
   504
template<class N, class E> EdgePoint OldGraph<N,E>::Edge(int f, int t)
alpar@1
   505
{
alpar@1
   506
  EdgePoint e;
alpar@1
   507
  
alpar@1
   508
  for(e=nodes[f].firstout;e&&e->to!=t;e=e->nextout) ;
alpar@1
   509
  
alpar@1
   510
  return (EdgePoint) e;
alpar@1
   511
}
alpar@1
   512
alpar@1
   513
template<class N, class E> void OldGraph<N,E>::Reverse(EdgePoint e)
alpar@1
   514
{
alpar@1
   515
  if(!e) return;
alpar@1
   516
alpar@1
   517
  nodes[e->from].outdeg--; nodes[e->to].indeg--;
alpar@1
   518
  
alpar@1
   519
  if(e->previn)
alpar@1
   520
    e->previn->nextin=e->nextin;
alpar@1
   521
  else nodes[e->to].firstin=e->nextin;
alpar@1
   522
  if(e->prevout)
alpar@1
   523
    e->prevout->nextout=e->nextout;
alpar@1
   524
  else nodes[e->from].firstout=e->nextout;
alpar@1
   525
  if(e->nextin)
alpar@1
   526
    e->nextin->previn=e->previn;
alpar@1
   527
  if(e->nextout)
alpar@1
   528
    e->nextout->prevout=e->prevout;
alpar@1
   529
  
alpar@1
   530
  int t,f;
alpar@1
   531
  f=e->to;e->to=t=e->from;
alpar@1
   532
  e->from=f;
alpar@1
   533
alpar@1
   534
  e->previn=e->prevout=NULL;
alpar@1
   535
  e->nextin=nodes[t].firstin;
alpar@1
   536
  e->nextout=nodes[f].firstout;
alpar@1
   537
  if(nodes[t].firstin) nodes[t].firstin->previn=e;
alpar@1
   538
  if(nodes[f].firstout) nodes[f].firstout->prevout=e;
alpar@1
   539
  nodes[t].firstin=nodes[f].firstout=e;
alpar@1
   540
  nodes[t].indeg++; nodes[f].outdeg++;
alpar@1
   541
alpar@1
   542
}
alpar@1
   543
alpar@1
   544
template<class N, class E> void OldGraph<N,E>::DeleteEdges()
alpar@1
   545
{
alpar@1
   546
  int n;
alpar@1
   547
  for(n=FirstNode();n!=INVALID;n=NextNode(n))
alpar@1
   548
    while(FirstOut(n)) Delete(FirstOut(n));
alpar@1
   549
}
alpar@1
   550
alpar@1
   551
#endif