11 #include "book_merge.h"
\r
31 static book_t In1[1];
\r
32 static book_t In2[1];
\r
33 static book_t Out[1];
\r
37 static void book_clear (book_t * book);
\r
39 static void book_open (book_t * book, const char file_name[], const char mode[]);
\r
40 static void book_close (book_t * book);
\r
42 static bool read_entry (book_t * book, entry_t * entry, int n);
\r
43 static void write_entry (book_t * book, const entry_t * entry);
\r
45 static uint64 read_integer (FILE * file, int size);
\r
46 static void write_integer (FILE * file, int size, uint64 n);
\r
52 void book_merge(int argc, char * argv[]) {
\r
55 const char * in_file_1;
\r
56 const char * in_file_2;
\r
57 const char * out_file;
\r
60 entry_t e1[1], e2[1];
\r
64 my_string_clear(&in_file_1);
\r
67 my_string_clear(&in_file_2);
\r
70 my_string_set(&out_file,"out.bin");
\r
72 for (i = 1; i < argc; i++) {
\r
76 } else if (my_string_equal(argv[i],"merge-book")) {
\r
80 } else if (my_string_equal(argv[i],"-in1")) {
\r
83 if (argv[i] == NULL) my_fatal("book_merge(): missing argument\n");
\r
85 my_string_set(&in_file_1,argv[i]);
\r
87 } else if (my_string_equal(argv[i],"-in2")) {
\r
90 if (argv[i] == NULL) my_fatal("book_merge(): missing argument\n");
\r
92 my_string_set(&in_file_2,argv[i]);
\r
94 } else if (my_string_equal(argv[i],"-out")) {
\r
97 if (argv[i] == NULL) my_fatal("book_merge(): missing argument\n");
\r
99 my_string_set(&out_file,argv[i]);
\r
103 my_fatal("book_merge(): unknown option \"%s\"\n",argv[i]);
\r
111 book_open(In1,in_file_1,"rb");
\r
112 book_open(In2,in_file_2,"rb");
\r
113 book_open(Out,out_file,"wb");
\r
122 b1 = read_entry(In1,e1,i1);
\r
123 b2 = read_entry(In2,e2,i2);
\r
127 } else if (!b1 && !b2) {
\r
131 } else if (b1 && !b2) {
\r
133 write_entry(Out,e1);
\r
136 } else if (b2 && !b1) {
\r
138 write_entry(Out,e2);
\r
147 } else if (e1->key < e2->key) {
\r
148 write_entry(Out,e1);
\r
150 } else if (e1->key > e2->key) {
\r
151 write_entry(Out,e2);
\r
154 ASSERT(e1->key==e2->key);
\r
166 printf("skipped %d entr%s.\n",skip,(skip>1)?"ies":"y");
\r
174 static void book_clear(book_t * book) {
\r
176 ASSERT(book!=NULL);
\r
184 static void book_open(book_t * book, const char file_name[], const char mode[]) {
\r
186 ASSERT(book!=NULL);
\r
187 ASSERT(file_name!=NULL);
\r
188 ASSERT(mode!=NULL);
\r
190 book->file = fopen(file_name,mode);
\r
191 if (book->file == NULL) my_fatal("book_open(): can't open file \"%s\": %s\n",file_name,strerror(errno));
\r
193 if (fseek(book->file,0,SEEK_END) == -1) {
\r
194 my_fatal("book_open(): fseek(): %s\n",strerror(errno));
\r
197 book->size = ftell(book->file) / 16;
\r
202 static void book_close(book_t * book) {
\r
204 ASSERT(book!=NULL);
\r
206 if (fclose(book->file) == EOF) {
\r
207 my_fatal("book_close(): fclose(): %s\n",strerror(errno));
\r
213 static bool read_entry(book_t * book, entry_t * entry, int n) {
\r
215 ASSERT(book!=NULL);
\r
216 ASSERT(entry!=NULL);
\r
218 if (n < 0 || n >= book->size) return false;
\r
220 ASSERT(n>=0&&n<book->size);
\r
222 if (fseek(book->file,n*16,SEEK_SET) == -1) {
\r
223 my_fatal("read_entry(): fseek(): %s\n",strerror(errno));
\r
226 entry->key = read_integer(book->file,8);
\r
227 entry->move = read_integer(book->file,2);
\r
228 entry->count = read_integer(book->file,2);
\r
229 entry->n = read_integer(book->file,2);
\r
230 entry->sum = read_integer(book->file,2);
\r
237 static void write_entry(book_t * book, const entry_t * entry) {
\r
239 ASSERT(book!=NULL);
\r
240 ASSERT(entry!=NULL);
\r
242 write_integer(book->file,8,entry->key);
\r
243 write_integer(book->file,2,entry->move);
\r
244 write_integer(book->file,2,entry->count);
\r
245 write_integer(book->file,2,entry->n);
\r
246 write_integer(book->file,2,entry->sum);
\r
251 static uint64 read_integer(FILE * file, int size) {
\r
257 ASSERT(file!=NULL);
\r
258 ASSERT(size>0&&size<=8);
\r
262 for (i = 0; i < size; i++) {
\r
268 my_fatal("read_integer(): fgetc(): EOF reached\n");
\r
270 my_fatal("read_integer(): fgetc(): %s\n",strerror(errno));
\r
274 ASSERT(b>=0&&b<256);
\r
283 static void write_integer(FILE * file, int size, uint64 n) {
\r
288 ASSERT(file!=NULL);
\r
289 ASSERT(size>0&&size<=8);
\r
290 ASSERT(size==8||n>>(size*8)==0);
\r
292 for (i = size-1; i >= 0; i--) {
\r
294 b = (n >> (i*8)) & 0xFF;
\r
295 ASSERT(b>=0&&b<256);
\r
297 if (fputc(b,file) == EOF) {
\r
298 my_fatal("write_integer(): fputc(): %s\n",strerror(errno));
\r
303 // end of book_merge.cpp
\r