logger_tools.c 7.56 KB
Newer Older
Loic Hausammann's avatar
Loic Hausammann committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*******************************************************************************
 * This file is part of SWIFT.
 * Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/
19
#include "logger_tools.h"
20
#include "logger_header.h"
Loic Hausammann's avatar
Loic Hausammann committed
21
#include "logger_loader_io.h"
Loic Hausammann's avatar
Loic Hausammann committed
22
#include "logger_reader.h"
23

24
#include "logger_particle.h"
25
26
27

#include <stdio.h>

28
/**
Loic Hausammann's avatar
Loic Hausammann committed
29
 * @brief get the offset of the next corresponding record.
30
31
32
 *
 * @param h #header structure of the file
 * @param map file mapping
Loic Hausammann's avatar
Loic Hausammann committed
33
 * @param offset In: initial offset, Out: offset of the next record
Loic Hausammann's avatar
Loic Hausammann committed
34
 * @param file_size The file size.
35
 *
Loic Hausammann's avatar
Loic Hausammann committed
36
 * @return -1 if no next record, otherwise 0
37
 */
Loic Hausammann's avatar
Loic Hausammann committed
38
int tools_get_next_record(const struct header *h, void *map, size_t *offset,
Loic Hausammann's avatar
Loic Hausammann committed
39
                          size_t file_size) {
Loic Hausammann's avatar
Loic Hausammann committed
40
  if (header_is_forward(h))
Loic Hausammann's avatar
Loic Hausammann committed
41
    return _tools_get_next_record_forward(h, map, offset);
Loic Hausammann's avatar
Loic Hausammann committed
42
  if (header_is_backward(h))
Loic Hausammann's avatar
Loic Hausammann committed
43
    return _tools_get_next_record_backward(h, map, offset, file_size);
44
  else
45
    error("Offsets are corrupted.");
46
47
}

48
/**
Loic Hausammann's avatar
Loic Hausammann committed
49
50
 * @brief internal function of #tools_get_next_record. Should not be used
 * outside.
51
52
53
 *
 * @param h #header structure of the file
 * @param map file mapping
54
 * @param offset (Out) offset of the next record
55
 *
Loic Hausammann's avatar
Loic Hausammann committed
56
 * @return error code, -1 if no next record
57
 */
Loic Hausammann's avatar
Loic Hausammann committed
58
int _tools_get_next_record_forward(const struct header *h, void *map,
Loic Hausammann's avatar
Loic Hausammann committed
59
                                   size_t *offset) {
60
61
  size_t diff_offset = 0;

Loic Hausammann's avatar
Loic Hausammann committed
62
  /* Read the offset. */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
63
64
  map =
      logger_loader_io_read_mask(h, (char *)map + *offset, NULL, &diff_offset);
65
66
67

  if (diff_offset == 0) return -1;

Loic Hausammann's avatar
Loic Hausammann committed
68
  /* Set the absolute offset. */
69
  *offset += diff_offset;
70
71
72
  return 0;
}

73
/**
Loic Hausammann's avatar
Loic Hausammann committed
74
 * @brief internal function of #tools_get_next_record. Should not be used (very
75
76
77
78
 * slow)
 *
 * @param h #header structure of the file
 * @param map file mapping
Loic Hausammann's avatar
Loic Hausammann committed
79
 * @param offset In: initial offset, Out: offset of the next record
Loic Hausammann's avatar
Loic Hausammann committed
80
 * @param file_size The file size.
81
 *
Loic Hausammann's avatar
Loic Hausammann committed
82
 * @return error code, -1 if no next record
83
 */
Loic Hausammann's avatar
Loic Hausammann committed
84
int _tools_get_next_record_backward(const struct header *h, void *map,
Loic Hausammann's avatar
Loic Hausammann committed
85
                                    size_t *offset, size_t file_size) {
86
#ifndef SWIFT_DEBUG_CHECKS
87
  error("Should not be used, method too slow");
88
89
#endif
  size_t current_offset = *offset;
Loic Hausammann's avatar
Loic Hausammann committed
90
  size_t record_header = LOGGER_MASK_SIZE + LOGGER_OFFSET_SIZE;
91
92
93
94

  while (current_offset < file_size) {
    size_t mask = 0;
    size_t prev_offset;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
95
96
    logger_loader_io_read_mask(h, (char *)map + current_offset, &mask,
                               &prev_offset);
Loic Hausammann's avatar
Loic Hausammann committed
97

Loic Hausammann's avatar
Loic Hausammann committed
98
    prev_offset = current_offset - prev_offset - record_header;
99
    if (*offset == prev_offset) {
Loic Hausammann's avatar
Loic Hausammann committed
100
      *offset = current_offset - record_header;
101
102
103
      return 0;
    }

Loic Hausammann's avatar
Loic Hausammann committed
104
    current_offset += header_get_record_size_from_mask(h, mask);
105
106
107
108
109
  }

  return -1;
}

110
/**
Loic Hausammann's avatar
Loic Hausammann committed
111
 * @brief switch side offset.
112
 *
Loic Hausammann's avatar
Loic Hausammann committed
113
 * From current record, switch side of the offset of the previous one.
Loic Hausammann's avatar
Loic Hausammann committed
114
 * @param h #header structure of the file.
115
 * @param file_map file mapping.
Loic Hausammann's avatar
Loic Hausammann committed
116
 * @param offset position of the record.
117
 *
Loic Hausammann's avatar
Loic Hausammann committed
118
 * @return position after the record.
119
 */
Loic Hausammann's avatar
Loic Hausammann committed
120
121
size_t tools_reverse_offset(const struct header *h, void *file_map,
                            size_t offset) {
122
123
  size_t mask = 0;
  size_t prev_offset = 0;
Loic Hausammann's avatar
Loic Hausammann committed
124
  const size_t cur_offset = offset;
125
  void *map = file_map;
126

Loic Hausammann's avatar
Loic Hausammann committed
127
  /* read mask + offset. */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
128
129
  map =
      logger_loader_io_read_mask(h, (char *)map + offset, &mask, &prev_offset);
130

Loic Hausammann's avatar
Loic Hausammann committed
131
  /* write offset of zero (in case it is the last record). */
132
  const size_t zero = 0;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
133
  map = (char *)map - LOGGER_OFFSET_SIZE;
Loic Hausammann's avatar
Loic Hausammann committed
134
  map = logger_loader_io_write_data(map, LOGGER_OFFSET_SIZE, &zero);
135

Loic Hausammann's avatar
Loic Hausammann committed
136
  /* set offset after current record. */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
137
138
  map = (char *)map + header_get_record_size_from_mask(h, mask);
  size_t after_current_record = (size_t)((char *)map - (char *)file_map);
139

Loic Hausammann's avatar
Loic Hausammann committed
140
  /* first records do not have a previous partner. */
Loic Hausammann's avatar
Loic Hausammann committed
141
  if (prev_offset == cur_offset) return after_current_record;
142
143

  if (prev_offset > cur_offset)
144
    error("Unexpected offset: header %lu, current %lu.", prev_offset,
145
146
          cur_offset);

Loic Hausammann's avatar
Loic Hausammann committed
147
  /* modify previous offset. */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
148
  map = (char *)file_map + cur_offset - prev_offset + LOGGER_MASK_SIZE;
Loic Hausammann's avatar
Loic Hausammann committed
149
  map = logger_loader_io_write_data(map, LOGGER_OFFSET_SIZE, &prev_offset);
150
151
152

#ifdef SWIFT_DEBUG_CHECKS
  size_t prev_mask = 0;
Loic Hausammann's avatar
Loic Hausammann committed
153
  map = (char *)map - LOGGER_MASK_SIZE - LOGGER_OFFSET_SIZE;
Loic Hausammann's avatar
Loic Hausammann committed
154
  logger_loader_io_read_mask(h, map, &prev_mask, NULL);
155

Loic Hausammann's avatar
Loic Hausammann committed
156
157
158
  /* Check if we are not mixing timestamp and particles */
  if ((prev_mask != h->timestamp_mask && mask == h->timestamp_mask) ||
      (prev_mask == h->timestamp_mask && mask != h->timestamp_mask))
159
    error("Unexpected mask: %lu, got %lu.", mask, prev_mask);
160
161

#endif  // SWIFT_DEBUG_CHECKS
Loic Hausammann's avatar
Loic Hausammann committed
162

163
  return after_current_record;
164
165
}

166
/**
Loic Hausammann's avatar
Loic Hausammann committed
167
 * @brief debugging function checking the offset and the mask of a record.
168
169
 *
 * Compare the mask with the one pointed by the header.
Loic Hausammann's avatar
Loic Hausammann committed
170
 * if the record is a particle, check the id too.
171
 *
Loic Hausammann's avatar
Loic Hausammann committed
172
173
174
175
 * @param reader The #logger_reader.
 * @param offset position of the record.
 *
 * @return position after the record.
176
 */
Loic Hausammann's avatar
Loic Hausammann committed
177
178
size_t tools_check_record_consistency(const struct logger_reader *reader,
                                      size_t offset) {
179
#ifndef SWIFT_DEBUG_CHECKS
180
  error("Should not check in non debug mode.");
181
182
#endif

Loic Hausammann's avatar
Loic Hausammann committed
183
  const struct header *h = &reader->log.header;
184
  void *file_init = reader->log.log.map;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
185
  void *map = (char *)file_init + offset;
186
187
188
189

  size_t mask;
  size_t pointed_offset;

Loic Hausammann's avatar
Loic Hausammann committed
190
  /* read mask + offset. */
Loic Hausammann's avatar
Loic Hausammann committed
191
  map = logger_loader_io_read_mask(h, map, &mask, &pointed_offset);
Loic Hausammann's avatar
Loic Hausammann committed
192

Loic Hausammann's avatar
Loic Hausammann committed
193
  /* get absolute offset. */
Loic Hausammann's avatar
Loic Hausammann committed
194
  if (header_is_forward(h))
195
    pointed_offset += offset;
Loic Hausammann's avatar
Loic Hausammann committed
196
  else if (header_is_backward(h)) {
197
    if (offset < pointed_offset)
198
      error("Offset too large (%lu) at %lu with mask %lu.", pointed_offset,
Loic Hausammann's avatar
Loic Hausammann committed
199
            offset, mask);
200
    pointed_offset = offset - pointed_offset;
Loic Hausammann's avatar
Loic Hausammann committed
201
  } else {
202
    error("Offset are corrupted.");
Loic Hausammann's avatar
Loic Hausammann committed
203
  }
204

Loic Hausammann's avatar
Loic Hausammann committed
205
  /* set offset after current record. */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
206
  map = (char *)+header_get_record_size_from_mask(h, mask);
207

208
  if (pointed_offset == offset || pointed_offset == 0)
Loic Hausammann's avatar
Format    
Loic Hausammann committed
209
    return (size_t)((char *)map - (char *)file_init);
210

Loic Hausammann's avatar
Loic Hausammann committed
211
  /* read mask of the pointed record. */
212
  size_t pointed_mask = 0;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
213
214
  logger_loader_io_read_mask(h, (char *)file_init + pointed_offset,
                             &pointed_mask, NULL);
215

Loic Hausammann's avatar
Loic Hausammann committed
216
217
218
  /* check if not mixing timestamp and particles. */
  if ((pointed_mask != h->timestamp_mask && mask == h->timestamp_mask) ||
      (pointed_mask == h->timestamp_mask && mask != h->timestamp_mask))
219
    error("Error in the offset (mask %lu at %lu != %lu at %lu).", mask, offset,
220
          pointed_mask, pointed_offset);
221

Loic Hausammann's avatar
Format    
Loic Hausammann committed
222
223
  if (pointed_mask == h->timestamp_mask)
    return (size_t)((char *)map - (char *)file_init);
224

Loic Hausammann's avatar
Loic Hausammann committed
225
  struct logger_particle part;
226
  logger_particle_read(&part, reader, offset, 0, logger_reader_const);
227

Loic Hausammann's avatar
Loic Hausammann committed
228
  long long id = part.id;
229
  logger_particle_read(&part, reader, pointed_offset, 0, logger_reader_const);
230

Loic Hausammann's avatar
Loic Hausammann committed
231
232
  if (id != part.id) {
    error("Offset wrong, id incorrect (%lli != %lli) at %lu.", id, part.id,
Loic Hausammann's avatar
Loic Hausammann committed
233
          pointed_offset);
Loic Hausammann's avatar
Loic Hausammann committed
234
  }
Loic Hausammann's avatar
Loic Hausammann committed
235

Loic Hausammann's avatar
Format    
Loic Hausammann committed
236
  return (size_t)((char *)map - (char *)file_init);
237
}