GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-37a74d03c4
rowio/get.c
Go to the documentation of this file.
1 /*!
2  \file rowio/get.c
3 
4  \brief RowIO library - Get a row
5 
6  (C) 2001-2009 by the GRASS Development Team
7 
8  This program is free software under the GNU General Public License
9  (>=v2). Read the file COPYING that comes with GRASS for details.
10 
11  \author Original author CERL
12  */
13 
14 #include <stdio.h>
15 #include <grass/rowio.h>
16 
17 static void *my_select(ROWIO *, int);
18 static void pageout(ROWIO *, int);
19 
20 /*!
21  * \brief Read a row
22  *
23  * Rowio_get() returns a buffer which holds the data for row from the
24  * file associated with ROWIO structure <i>R</i>. If the row requested
25  * is not in memory, the getrow() routine specified in
26  * Rowio_setup() is called to read row into memory and a
27  * pointer to the memory buffer containing the row is returned. If the
28  * data currently in the buffer had been changed by Rowio_put(),
29  * the putrow() routine specified in Rowio_setup() is
30  * called first to write the changed row to disk. If row is
31  * already in memory, no disk read is done. The pointer to the data is
32  * simply returned.
33  *
34  * \param R pointer to ROWIO structure
35  * \param row row number
36  *
37  * \return NULL on error
38  * \return pointer to the buffer containing row
39  */
40 void *Rowio_get(ROWIO *R, int row)
41 {
42  int i;
43  int age;
44  int cur;
45 
46  if (row < 0)
47  return NULL;
48 
49  if (row == R->cur)
50  return R->buf;
51 
52  for (i = 0; i < R->nrows; i++)
53  if (row == R->rcb[i].row)
54  return my_select(R, i);
55 
56  age = 0;
57  cur = 0;
58 
59  for (i = 0; i < R->nrows; i++)
60  if (R->rcb[i].row < 0) { /* free slot ! */
61  cur = i;
62  break;
63  }
64  else if (age < R->rcb[i].age) {
65  cur = i;
66  age = R->rcb[i].age;
67  }
68 
69  pageout(R, cur);
70 
71  i = (*R->getrow)(R->fd, R->rcb[cur].buf, R->rcb[cur].row = row, R->len);
72  R->rcb[cur].dirty = 0;
73  if (!i) {
74  R->rcb[cur].row = -1;
75  if (cur == R->cur)
76  R->cur = -1;
77  return NULL;
78  }
79 
80  return my_select(R, cur);
81 }
82 
83 /*!
84  \brief Flush data
85 
86  \param R pointer to ROWIO structure
87  */
89 {
90  int i;
91 
92  for (i = 0; i < R->nrows; i++)
93  pageout(R, i);
94 }
95 
96 static void pageout(ROWIO *R, int cur)
97 {
98  if (R->rcb[cur].row < 0)
99  return;
100  if (!R->rcb[cur].dirty)
101  return;
102  (*R->putrow)(R->fd, R->rcb[cur].buf, R->rcb[cur].row, R->len);
103  R->rcb[cur].dirty = 0;
104 }
105 
106 static void *my_select(ROWIO *R, int n)
107 {
108  int i;
109 
110  R->rcb[n].age = 0;
111  for (i = 0; i < R->nrows; i++)
112  R->rcb[i].age++;
113  R->cur = R->rcb[n].row;
114  R->buf = R->rcb[n].buf;
115  return R->buf;
116 }
#define NULL
Definition: ccmath.h:32
void Rowio_flush(ROWIO *R)
Flush data.
Definition: rowio/get.c:88
void * Rowio_get(ROWIO *R, int row)
Read a row.
Definition: rowio/get.c:40
void * buf
Definition: rowio.h:15
Definition: rowio.h:4
void * buf
Definition: rowio.h:9
int len
Definition: rowio.h:7
int(* getrow)(int, void *, int, int)
Definition: rowio.h:10
struct ROWIO::ROWIO_RCB * rcb
int fd
Definition: rowio.h:5
int(* putrow)(int, const void *, int, int)
Definition: rowio.h:11
int nrows
Definition: rowio.h:6
int cur
Definition: rowio.h:8