-
Notifications
You must be signed in to change notification settings - Fork 0
/
vector_file.hpp
135 lines (117 loc) · 3.63 KB
/
vector_file.hpp
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
//
// Copyright (c) 2017 – Technicolor R&D France
//
// The source code form of this open source project is subject to the terms of the
// Clear BSD license.
//
// You can redistribute it and/or modify it under the terms of the Clear BSD
// License (See LICENSE file).
//
#ifndef VECTOR_FILE_HPP_
#define VECTOR_FILE_HPP_
#include <cstdint>
#include <cstdarg>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
#include <fcntl.h>
#include <unistd.h>
#include <sstream>
int open_or_die(const char* filename, int flags) {
int fd = open(filename, flags);
if(fd == -1) {
std::stringstream ss;
ss << "Could not open file " << filename;
perror(ss.str().c_str());
exit(1);
}
return fd;
}
int open_or_die(const char* filename, int flags, mode_t mode) {
int fd = open(filename, flags, mode);
if(fd == -1) {
std::stringstream ss;
ss << "Could not open file " << filename;
perror(ss.str().c_str());
exit(1);
}
return fd;
}
void read_or_die(int fd, void* buf, size_t sz) {
ssize_t ssz = static_cast<size_t>(sz);
if(read(fd, buf, sz) != ssz) {
std::stringstream ss;
ss << "Could not read " << sz << " bytes from file";
perror(ss.str().c_str());
exit(1);
}
}
void write_or_die(int fd, const void* buf, size_t sz) {
ssize_t ssz = static_cast<size_t>(sz);
if(write(fd, buf, sz) != ssz) {
std::stringstream ss;
ss << "Could not write " << sz << " bytes from file";
perror(ss.str().c_str());
exit(1);
}
}
void filename_error(const char* filename) {
std::cerr << "Could not load vectors from " << filename << std::endl;
std::cerr << "Unknown extension\n";
std::cerr << "Known extensions: .bvecs, .ivecs, .fvecs" << std::endl;
exit(1);
}
int extension_to_component_size(const char* extension, const char* filename) {
if (!strcmp(extension, ".bvecs")) {
return 1;
} else if (!strcmp(extension, ".fvecs") || !strcmp(extension, ".ivecs")) {
return 4;
}
filename_error (filename);
return 0;
}
template<typename ... Args>
const char* check_extensions(const char* in_filename, Args ... filenames) {
const char* in_extension = strrchr(in_filename, '.');
const char* out_filenames[] = { filenames... };
for (auto&& out_filename : out_filenames) {
if (auto out_extension = strrchr(out_filename, '.')) {
if (strcmp(in_extension, out_extension)) {
std::cerr
<< "Input file and output files must have the same extension."
<< std::endl;
exit(1);
}
} else {
filename_error(out_filename);
}
}
return in_extension;
}
void sendfile_loop(int out_fd, int in_fd, off_t& offset, const size_t size) {
const off_t end = offset + size;
off_t remaining = size;
while(remaining > 0) {
const ssize_t ret = sendfile(out_fd, in_fd, &offset, remaining);
if(ret < 0) {
std::cerr << "Error while copying data to destination file." << std::endl;
exit(1);
}
remaining = end - offset;
}
}
std::int32_t read_dimension_rewind(int in_fd) {
std::int32_t dim;
if(read(in_fd, reinterpret_cast<void*>(&dim), sizeof(dim)) != sizeof(dim)) {
std::cerr << "Could not read vector dimension" << std::endl;
exit(1);
}
lseek(in_fd, 0, SEEK_SET);
return dim;
}
size_t tell_size_rewind(int in_fd) {
off_t end = lseek(in_fd, 0, SEEK_END);
lseek(in_fd, 0, SEEK_SET);
return static_cast<size_t>(end);
}
#endif /* VECTOR_FILE_HPP_ */