1/**2* Copyright 2013, GitHub, Inc3* Copyright 2009-2013, Daniel Lemire, Cliff Moon,4* David McIntosh, Robert Becho, Google Inc. and Veronika Zenz5*6* This program is free software; you can redistribute it and/or7* modify it under the terms of the GNU General Public License8* as published by the Free Software Foundation; either version 29* of the License, or (at your option) any later version.10*11* This program is distributed in the hope that it will be useful,12* but WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14* GNU General Public License for more details.15*16* You should have received a copy of the GNU General Public License17* along with this program; if not, write to the Free Software18* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.19*/20#include "git-compat-util.h"21#include "ewok.h"2223int ewah_serialize_native(struct ewah_bitmap *self, int fd)24{25uint32_t write32;26size_t to_write = self->buffer_size * 8;2728/* 32 bit -- bit size for the map */29write32 = (uint32_t)self->bit_size;30if (write(fd, &write32, 4) != 4)31return -1;3233/** 32 bit -- number of compressed 64-bit words */34write32 = (uint32_t)self->buffer_size;35if (write(fd, &write32, 4) != 4)36return -1;3738if (write(fd, self->buffer, to_write) != to_write)39return -1;4041/** 32 bit -- position for the RLW */42write32 = self->rlw - self->buffer;43if (write(fd, &write32, 4) != 4)44return -1;4546return (3 * 4) + to_write;47}4849int ewah_serialize_to(struct ewah_bitmap *self,50int (*write_fun)(void *, const void *, size_t),51void *data)52{53size_t i;54eword_t dump[2048];55const size_t words_per_dump = sizeof(dump) / sizeof(eword_t);56uint32_t bitsize, word_count, rlw_pos;5758const eword_t *buffer;59size_t words_left;6061/* 32 bit -- bit size for the map */62bitsize = htonl((uint32_t)self->bit_size);63if (write_fun(data, &bitsize, 4) != 4)64return -1;6566/** 32 bit -- number of compressed 64-bit words */67word_count = htonl((uint32_t)self->buffer_size);68if (write_fun(data, &word_count, 4) != 4)69return -1;7071/** 64 bit x N -- compressed words */72buffer = self->buffer;73words_left = self->buffer_size;7475while (words_left >= words_per_dump) {76for (i = 0; i < words_per_dump; ++i, ++buffer)77dump[i] = htonll(*buffer);7879if (write_fun(data, dump, sizeof(dump)) != sizeof(dump))80return -1;8182words_left -= words_per_dump;83}8485if (words_left) {86for (i = 0; i < words_left; ++i, ++buffer)87dump[i] = htonll(*buffer);8889if (write_fun(data, dump, words_left * 8) != words_left * 8)90return -1;91}9293/** 32 bit -- position for the RLW */94rlw_pos = (uint8_t*)self->rlw - (uint8_t *)self->buffer;95rlw_pos = htonl(rlw_pos / sizeof(eword_t));9697if (write_fun(data, &rlw_pos, 4) != 4)98return -1;99100return (3 * 4) + (self->buffer_size * 8);101}102103static int write_helper(void *fd, const void *buf, size_t len)104{105return write((intptr_t)fd, buf, len);106}107108int ewah_serialize(struct ewah_bitmap *self, int fd)109{110return ewah_serialize_to(self, write_helper, (void *)(intptr_t)fd);111}112113int ewah_read_mmap(struct ewah_bitmap *self, void *map, size_t len)114{115uint32_t *read32 = map;116eword_t *read64;117size_t i;118119self->bit_size = ntohl(*read32++);120self->buffer_size = self->alloc_size = ntohl(*read32++);121self->buffer = ewah_realloc(self->buffer,122self->alloc_size * sizeof(eword_t));123124if (!self->buffer)125return -1;126127for (i = 0, read64 = (void *)read32; i < self->buffer_size; ++i)128self->buffer[i] = ntohll(*read64++);129130read32 = (void *)read64;131self->rlw = self->buffer + ntohl(*read32++);132133return (3 * 4) + (self->buffer_size * 8);134}135136int ewah_deserialize(struct ewah_bitmap *self, int fd)137{138size_t i;139eword_t dump[2048];140const size_t words_per_dump = sizeof(dump) / sizeof(eword_t);141uint32_t bitsize, word_count, rlw_pos;142143eword_t *buffer = NULL;144size_t words_left;145146ewah_clear(self);147148/* 32 bit -- bit size for the map */149if (read(fd, &bitsize, 4) != 4)150return -1;151152self->bit_size = (size_t)ntohl(bitsize);153154/** 32 bit -- number of compressed 64-bit words */155if (read(fd, &word_count, 4) != 4)156return -1;157158self->buffer_size = self->alloc_size = (size_t)ntohl(word_count);159self->buffer = ewah_realloc(self->buffer,160self->alloc_size * sizeof(eword_t));161162if (!self->buffer)163return -1;164165/** 64 bit x N -- compressed words */166buffer = self->buffer;167words_left = self->buffer_size;168169while (words_left >= words_per_dump) {170if (read(fd, dump, sizeof(dump)) != sizeof(dump))171return -1;172173for (i = 0; i < words_per_dump; ++i, ++buffer)174*buffer = ntohll(dump[i]);175176words_left -= words_per_dump;177}178179if (words_left) {180if (read(fd, dump, words_left * 8) != words_left * 8)181return -1;182183for (i = 0; i < words_left; ++i, ++buffer)184*buffer = ntohll(dump[i]);185}186187/** 32 bit -- position for the RLW */188if (read(fd, &rlw_pos, 4) != 4)189return -1;190191self->rlw = self->buffer + ntohl(rlw_pos);192return 0;193}