~wattazoum/albert/albert-mod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/******************************************************************/
/***  FILE :        node_mgt.c                                  ***/
/***  AUTHOR:       David P. Jacobs                             ***/
/***  PROGRAMMER:   David Lee                                   ***/
/***  DATE WRITTEN: Aug 1992.                                   ***/
/***  PUBLIC ROUTINES:                                          ***/
/***      GetRecord()                                           ***/
/***      PutRecord()                                           ***/
/***      DestroySparseMatrix()                                 ***/
/***                                                            ***/
/***  PRIVATE ROUTINES:                                         ***/
/***  MODULE DESCRIPTION:                                       ***/
/***      This module contains the routines for albert          ***/
/***      node memory management. As a node record is needed    ***/
/***      a call GetRecord() is made. These routines retreive   ***/
/***      an unused node off of the free list whose head is     ***/
/***      the node_list_head pointer. When there are no free    ***/
/***      nodes left then a new block of nodes is allocated     ***/
/***      and carved up into a new list. Deallocated nodes are  ***/
/***      placed on the front of this list. As new blocks are   ***/
/***      needed they are allocated and linked by the next      ***/
/***      block field in the block structure.                   ***/
/***      When the information has been extracted from the      ***/
/***      matrix DestroySparseMatrix() is called and the        ***/
/***      list of blocks is stepped thru and deleted            ***/
/***                                                            ***/
/******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "Sparse_structs.h"
#include "Sparse_defs.h"
#include "Debug.h"
#include "node_mgt.h"
#include  "Memory_routines.h"


static mem_block *block_list_head=NULL;
static mem_block *current_block=NULL;
static Node *node_list_head=NULL;

#ifdef DEBUGMM
static short int blocknum=0;
#endif

Node *GetRecord() 
{
    Node *return_value = NULL;
    mem_block *new_block;
    int i;

    /* if there are no free nodes available then allocate new ones */

    if (node_list_head ==NULL)
    {
       new_block = (mem_block *) Mymalloc (sizeof(mem_block));
#ifdef DEBUGMM
       new_block->id = blocknum;
       printf("Allocated block #%d\n",new_block->id);
       blocknum++;
#endif
       new_block->next_block=NULL;

       /* if this is the first block make it the head of the list */

       if (block_list_head==NULL)
       {
          block_list_head=new_block;
          current_block=new_block;
       }

       /* else connect it to the list and make it current */

       else
       {
          current_block->next_block=new_block;
          current_block=current_block->next_block;
          current_block=new_block; 
       }
       node_list_head=new_block->record;
         
       /* carve it up into a linked list */

       for (i=0;i < (RECORDS_PER_BLOCK-1);i++)
       { 
          new_block->record[i].Next_Node = &new_block->record[i+1];
       }
       new_block->record[i].Next_Node=NULL;
	}
 
   /* return the front node in the list */

   return_value = node_list_head;

   /* move the pointer to the next one */

   node_list_head=node_list_head->Next_Node;
          
   return (return_value);
}


void PutRecord(freed_node)
Node *freed_node;
{

  /* Null out information in the node to be safe */

  freed_node->element= -1;
  freed_node->column= -1;
  freed_node->Next_Node=NULL;

  /* return it to the front of the list */

  freed_node->Next_Node=node_list_head;
  node_list_head=freed_node;

  return;
}

DestroySparseMatrix(Sparse_Matrix)
MAT_PTR Sparse_Matrix;
{

    mem_block *block_ptr,*prev_block_ptr;

    /* if no blocks allocated then there is no matrix to destroy */

    if (block_list_head==NULL)
    return;
    block_ptr = block_list_head;
    prev_block_ptr = block_list_head;

    /* walk the list deleting blocks behind us */
    while (block_ptr != NULL)
    {
       prev_block_ptr = block_ptr;
       block_ptr = block_ptr->next_block;
#ifdef DEBUGMM
       printf("Freeing block #%d\n",prev_block_ptr->id);
#endif
       free(prev_block_ptr);
    }

    /*free the row pointers */

    free(Sparse_Matrix);

    /* null out static variables */

    block_list_head=NULL;
    node_list_head=NULL;
    current_block=NULL;
#ifdef DEBUGMM
     blocknum=0;
#endif
    return; 
}