GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
Loading...
Searching...
No Matches
pagein.c
Go to the documentation of this file.
1/**
2 * \file pagein.c
3 *
4 * \brief Segment page-in routines.
5 *
6 * This program is free software under the GNU General Public License
7 * (>=v2). Read the file COPYING that comes with GRASS for details.
8 *
9 * \author GRASS GIS Development Team
10 *
11 * \date 2005-2009
12 */
13
14#include <stdio.h>
15#include <unistd.h>
16#include <string.h>
17#include <errno.h>
18#include <grass/gis.h>
19#include "local_proto.h"
20
21/**
22 * \brief Internal use only
23 *
24 * Segment pagein.
25 *
26 * Finds <b>n</b> in the segment file, <b>seg</b>, and selects it as the
27 * current segment.
28 *
29 * \param[in] SEG segment
30 * \param[in] n segment number
31 * \return 1 if successful
32 * \return -1 if unable to seek or read segment file
33 */
34
35int seg_pagein(SEGMENT *SEG, int n)
36{
37 int cur;
38 int read_result;
39
40 /* is n the current segment? */
41 if (n == SEG->scb[SEG->cur].n)
42 return SEG->cur;
43
44 /* segment n is in memory ? */
45
46 if (SEG->load_idx[n] >= 0) {
47 cur = SEG->load_idx[n];
48
49 if (SEG->scb[cur].age != SEG->youngest) {
50 /* splice out */
51 SEG->scb[cur].age->younger->older = SEG->scb[cur].age->older;
52 SEG->scb[cur].age->older->younger = SEG->scb[cur].age->younger;
53 /* splice in */
54 SEG->scb[cur].age->younger = SEG->youngest->younger;
55 SEG->scb[cur].age->older = SEG->youngest;
56 SEG->scb[cur].age->older->younger = SEG->scb[cur].age;
57 SEG->scb[cur].age->younger->older = SEG->scb[cur].age;
58 /* make it youngest */
59 SEG->youngest = SEG->scb[cur].age;
60 }
61
62 return SEG->cur = cur;
63 }
64
65 /* find a slot to use to hold segment */
66 if (!SEG->nfreeslots) {
67 /* use oldest segment */
68 SEG->oldest = SEG->oldest->younger;
69 cur = SEG->oldest->cur;
70 SEG->oldest->cur = -1;
71
72 /* unload segment */
73 if (SEG->scb[cur].n >= 0) {
74 SEG->load_idx[SEG->scb[cur].n] = -1;
75
76 /* write it out if dirty */
77 if (SEG->scb[cur].dirty) {
78 if (seg_pageout(SEG, cur) < 0)
79 return -1;
80 }
81 }
82 }
83 else {
84 /* free slots left */
85 cur = SEG->freeslot[--SEG->nfreeslots];
86 }
87
88 /* read in the segment */
89 SEG->scb[cur].n = n;
90 SEG->scb[cur].dirty = 0;
91 SEG->seek(SEG, SEG->scb[cur].n, 0);
92
93 read_result = read(SEG->fd, SEG->scb[cur].buf, SEG->size);
94
95 if (read_result == 0) {
96 /* this can happen if the file was not zero-filled,
97 * i.e. formatted with Segment_format_nofill() or
98 * Segment_format() used lseek for file initialization */
99 G_debug(1, "Segment pagein: zero read");
100 memset(SEG->scb[cur].buf, 0, SEG->size);
101 }
102 else if (read_result != SEG->size) {
103 G_debug(2, "Segment pagein: read_result=%d SEG->size=%d", read_result,
104 SEG->size);
105
106 if (read_result < 0)
107 G_warning("Segment pagein: %s", strerror(errno));
108 else
109 G_warning("Segment pagein: short count during read(), got %d, "
110 "expected %d",
111 read_result, SEG->size);
112
113 return -1;
114 }
115
116 /* add loaded segment to index */
117 SEG->load_idx[n] = cur;
118
119 /* make it youngest segment */
120 SEG->youngest = SEG->youngest->younger;
121 SEG->scb[cur].age = SEG->youngest;
122 SEG->youngest->cur = cur;
123
124 return SEG->cur = cur;
125}
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition gis/error.c:203
int seg_pagein(SEGMENT *SEG, int n)
Internal use only.
Definition pagein.c:35
int seg_pageout(SEGMENT *SEG, int i)
Internal use only.
Definition pageout.c:35