10
10
* \author GRASS GIS Development Team
16
16
#include <unistd.h>
17
17
#include <string.h>
19
#include <grass/segment.h>
22
static int segment_select(SEGMENT *, int);
19
#include <grass/gis.h>
20
#include "local_proto.h"
26
* \fn int segment_pagein (SEGMENT *SEG, int n)
28
* \brief Segment pagein.
24
* \brief Internal use only
30
28
* Finds <b>n</b> in the segment file, <b>seg</b>, and selects it as the
33
* \param[in] seg segment
31
* \param[in] SEG segment
34
32
* \param[in] n segment number
35
33
* \return 1 if successful
36
34
* \return -1 if unable to seek or read segment file
39
int segment_pagein(SEGMENT * SEG, int n)
37
int seg_pagein(SEGMENT * SEG, int n)
46
42
/* is n the current segment? */
47
43
if (n == SEG->scb[SEG->cur].n)
50
/* search the in memory segments */
51
for (i = 0; i < SEG->nseg; i++)
52
if (n == SEG->scb[i].n)
53
return segment_select(SEG, i);
46
/* segment n is in memory ? */
48
if (SEG->load_idx[n] >= 0) {
49
cur = SEG->load_idx[n];
51
if (SEG->scb[cur].age != SEG->youngest) {
53
SEG->scb[cur].age->younger->older = SEG->scb[cur].age->older;
54
SEG->scb[cur].age->older->younger = SEG->scb[cur].age->younger;
56
SEG->scb[cur].age->younger = SEG->youngest->younger;
57
SEG->scb[cur].age->older = SEG->youngest;
58
SEG->scb[cur].age->older->younger = SEG->scb[cur].age;
59
SEG->scb[cur].age->younger->older = SEG->scb[cur].age;
60
/* make it youngest */
61
SEG->youngest = SEG->scb[cur].age;
64
return SEG->cur = cur;
55
67
/* find a slot to use to hold segment */
58
for (i = 0; i < SEG->nseg; i++)
59
if (SEG->scb[i].n < 0) { /* free slot */
63
else if (age < SEG->scb[i].age) { /* find oldest segment */
65
age = SEG->scb[i].age;
68
/* if slot is used, write it out, if dirty */
69
if (SEG->scb[cur].n >= 0 && SEG->scb[cur].dirty)
70
if (segment_pageout(SEG, cur) < 0)
68
if (!SEG->nfreeslots) {
69
/* use oldest segment */
70
SEG->oldest = SEG->oldest->younger;
71
cur = SEG->oldest->cur;
72
SEG->oldest->cur = -1;
75
if (SEG->scb[cur].n >= 0) {
76
SEG->load_idx[SEG->scb[cur].n] = -1;
78
/* write it out if dirty */
79
if (SEG->scb[cur].dirty) {
80
if (seg_pageout(SEG, cur) < 0)
87
cur = SEG->freeslot[--SEG->nfreeslots];
73
90
/* read in the segment */
74
91
SEG->scb[cur].n = n;
75
92
SEG->scb[cur].dirty = 0;
76
segment_seek(SEG, SEG->scb[cur].n, 0);
93
SEG->seek(SEG, SEG->scb[cur].n, 0);
78
95
read_result = read(SEG->fd, SEG->scb[cur].buf, SEG->size);
79
96
if (read_result != SEG->size) {
80
G_debug(2, "segment_pagein: read_result=%d SEG->size=%d",
97
G_debug(2, "Segment pagein: read_result=%d SEG->size=%d",
81
98
read_result, SEG->size);
83
100
if (read_result < 0)
84
G_warning("segment_pagein: %s", strerror(errno));
101
G_warning("Segment pagein: %s", strerror(errno));
85
102
else if (read_result == 0)
86
G_warning("segment_pagein: read EOF");
103
G_warning("Segment pagein: read EOF");
89
("segment_pagein: short count during read(), got %d, expected %d",
106
("Segment pagein: short count during read(), got %d, expected %d",
90
107
read_result, SEG->size);
95
return segment_select(SEG, cur);
99
static int segment_select(SEGMENT * SEG, int n)
104
for (i = 0; i < SEG->nseg; i++)
112
/* add loaded segment to index */
113
SEG->load_idx[n] = cur;
115
/* make it youngest segment */
116
SEG->youngest = SEG->youngest->younger;
117
SEG->scb[cur].age = SEG->youngest;
118
SEG->youngest->cur = cur;
120
return SEG->cur = cur;