/* ============================================================
 * Copyright (c) 2014 Actifio Inc. All Rights Reserved
 * =============================================================
 */

#include <stdlib.h>
#include <assert.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdbool.h>
#include <fcntl.h>

#include "bitmap.h"

extern int verbosity;

#define COMPRESSION_LEVEL 6

ram_bitmap_t *bitmap_create(uint64_t volsize, unsigned int grainsize)
{
        uint64_t size = sizeof(fc_bitmap_hdr_t) + sizeof(fc_bitmap_mq_hdr_t);
        /* Roundup to grainsize and to the next byte */
        uint64_t bmsize = (((volsize + grainsize - 1) / grainsize) + 8 - 1) / 8;

        if (volsize % LBAS_SIZE || grainsize % LBAS_SIZE) {
                printf("Invalid alignment: volsize/grainsize %"PRIi64"/%u "
                       "should be multible of LBAS %u\n", volsize, grainsize, LBAS_SIZE);
                return NULL;
        }
        if (volsize % grainsize) {
                printf("Invalid alignment: volsize %"PRIi64" should be multible of grainsize %u\n",
                       volsize, grainsize);
                return NULL;
        }
        size += bmsize;

        ram_bitmap_t * bitmap = (ram_bitmap_t *) malloc(size);

        assert(bitmap);
        memset(bitmap,0,size);

        bitmap->mqhdr.grain_size_lbas = grainsize/LBAS_SIZE;
        bitmap->mqhdr.vdisk_size_lbas = volsize/LBAS_SIZE;      
        bitmap->mqhdr.bitmap_size_bytes = bmsize;

        bitmap->mqhdr.bitmap_mq_magic[0] = ((FC_BITMAP_MQ_MAGIC >> 24) & 0xFF);
        bitmap->mqhdr.bitmap_mq_magic[1] = ((FC_BITMAP_MQ_MAGIC >> 16) & 0xFF);
        bitmap->mqhdr.bitmap_mq_magic[2] = ((FC_BITMAP_MQ_MAGIC >>  8) & 0xFF);
        bitmap->mqhdr.bitmap_mq_magic[3] = (FC_BITMAP_MQ_MAGIC & 0xFF);

        // Let's make sure we did this right.
        assert( bitmap->mqhdr.bitmap_size_bytes == bmsize);

        return bitmap;
}

ram_bitmap_t *bitmap_dup(ram_bitmap_t *bitmap)
{
	ram_bitmap_t *new_bitmap =
		bitmap_create(bitmap->mqhdr.vdisk_size_lbas*LBAS_SIZE,
			      bitmap->mqhdr.grain_size_lbas*LBAS_SIZE);
	if (new_bitmap)
		bcopy(&(bitmap->bits[0]), &(new_bitmap->bits[0]),
		      bitmap->mqhdr.bitmap_size_bytes);

	return (new_bitmap);
}

void bitmap_destroy(ram_bitmap_t *bitmap)
{
        free(bitmap);
}

ram_bitmap_pair_t *bitmap_pair_create(uint64_t volsize, unsigned int grainsize)
{
        ram_bitmap_pair_t *pair = malloc(sizeof(ram_bitmap_pair_t));
        if (pair == NULL)
		return NULL;

	pair->diff_bitmap = bitmap_create(volsize, grainsize);
	if (pair->diff_bitmap == NULL) {
		free(pair);
		return NULL;
	}

	pair->free_bitmap = bitmap_create(volsize, grainsize);
	if (pair->free_bitmap == NULL) {
		free(pair->diff_bitmap);
		free(pair);
		return NULL;
	}

	return pair;
}

void bitmap_pair_destroy(ram_bitmap_pair_t *pair)
{
	if (pair) {
		if (pair->free_bitmap)
			bitmap_destroy(pair->free_bitmap);
		if (pair->diff_bitmap)
			bitmap_destroy(pair->diff_bitmap);
		free(pair);
	}
}

void bitmap_addbit(ram_bitmap_t *diffbitmap, uint64_t rangeaddr, uint64_t rangesize)
{
        /*
         * Get the (first) grain that contains rangeaddr, get the (last) grain that contains
         * rangeadd+rangesize, then walk through the range of grains including the last 
         * changed grain and set the bits
         */
        uint64_t start_block = rangeaddr/(diffbitmap->mqhdr.grain_size_lbas * LBAS_SIZE);
        uint64_t end_block = (rangeaddr + rangesize - 1)/(diffbitmap->mqhdr.grain_size_lbas * LBAS_SIZE);
        uint64_t b;

        for (b = start_block; b <= end_block; b++) {
                uint64_t byte_idx = b / 8;
                int bit_idx = b % 8;
                diffbitmap->bits[byte_idx] |= (uint8_t)(1 << bit_idx);
        }
}

void bitmap_fwrite(const void *ptr, size_t size, size_t nmemb,
    FILE *stream)
{
        if (fwrite(ptr, size, nmemb, stream) != nmemb)
        {
                fprintf(stderr,"Error: cannot write to bitmap file\n");
                exit(-1);
        }
}


bool is_buffer_zeroed(unsigned char *buffer, uint64_t size)
{
    return !(bool)(*buffer || memcmp(buffer, buffer + 1, (size_t)size - 1));
}

/* This routine will keep calling pwrite until all the bytes in a block gets written. 
 * Subsequent pwrite calls will attempt to write only the remaining bytes. 
 * At any point of time if pwrite returns a value <= 0, error will be thrown.
 */
int pwrite_data(const int fd, const void *buf, size_t size, off_t write_offset)
{
        off_t read_offset = 0;
        int rem = size;
        while (rem) {
                int nbytes = pwrite(fd, buf + read_offset, rem, write_offset);
                if (nbytes <= 0)
                        return -1;
                rem -= nbytes;
                read_offset += nbytes;
                write_offset += nbytes;
        }
        return 0;
}
/* 
 * Write bitmap portion (without headers) of ram_bitmap_t in sparse manner
 */
int bitmap_write_sparse(const int fd, uint64_t bitmap_size_bytes, unsigned char *buf)
{
        ftruncate(fd, (FC_BITMAP_BITMAP_OFFSET + bitmap_size_bytes));
        int64_t i, remainder, chunks;
        off_t read_offset = 0;
        off_t write_offset = FC_BITMAP_BITMAP_OFFSET;
        chunks = bitmap_size_bytes / LBAS_SIZE;
        remainder = bitmap_size_bytes % LBAS_SIZE;

        for (i = 0; i < chunks; i++) {
                if (!(is_buffer_zeroed(&buf[read_offset], LBAS_SIZE))) {
                        if (pwrite_data(fd, buf + read_offset, LBAS_SIZE, write_offset) < 0)
                                return -1;
                }
                read_offset += LBAS_SIZE;
                write_offset += LBAS_SIZE;
        }

        if (remainder) {
                if (pwrite_data(fd, buf + read_offset, remainder, write_offset) < 0)
                        return -1;
        }
        return 0;
}

void bitmap_write(ram_bitmap_t *diff_bitmap, const char * bitmap)
{
        struct stat sb;
        int fd = open(bitmap, O_CREAT|O_WRONLY, 0666);
        if(fd < 0) {
                fprintf(stderr,"Error: cannot create bitmap file %s: %s\n", bitmap, strerror(errno));
                exit(-1);
        }

        if(fstat(fd, &sb)) {
                fprintf(stderr,"Error: cannot retrieve file info %s: %s\n", bitmap, strerror(errno));
                close(fd);
                exit(-1);
        }
        /* write out the bm header only if this is a new file
         * for existing bitmap, bmhdr is already up to date, we just need to update mqhdr and
         * the actual bitmap
         */
        if(!sb.st_size && (pwrite_data(fd, &diff_bitmap->bmhdr, sizeof(diff_bitmap->bmhdr), 0) < 0))
                goto write_fail;

        /* mqhdr needs to be updated even if it is an already existing file. Bitmap size (initially 0)
         * and other fields of mqhdr will be modified here
         */
        if (pwrite_data(fd, &diff_bitmap->mqhdr, sizeof(diff_bitmap->mqhdr), FC_BITMAP_MQ_HDR_OFFSET) < 0)
                goto write_fail;

        if (bitmap_write_sparse(fd, diff_bitmap->mqhdr.bitmap_size_bytes, diff_bitmap->bits) < 0)
                goto write_fail;

        if (close(fd)) {
                fprintf(stderr, "Error: unable to close fd %s: %s\n", bitmap, strerror(errno));
                exit(-1);
        }
        return;

write_fail:
        fprintf(stderr, "Error: unable to write bitmap %s : %s\n", bitmap, strerror(errno));
        close(fd);
        exit(-1);
}

extern size_t gzip_compress(void *src, void *dst, size_t s_len, size_t d_len, int level);
extern int gzip_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n);

/*
 * Because of runs of 1s, holemap files don't sparsify well.
 * This function will compress the bitmap portion of ram_bitmap_t before
 * persisting it to the disk
 */
void holemap_write(ram_bitmap_t *free_bitmap, const char * holemap)
{
        int exists = 0;
        struct stat sb;
        size_t nread;
        FILE *bm;
        unsigned char * compressed_bitmap;

        u_int64_t size = free_bitmap->mqhdr.bitmap_size_bytes;
        compressed_bitmap = (unsigned char *) malloc(size);
        assert(compressed_bitmap);
        memset(compressed_bitmap,0,size);

        /* In some cases compression output is worse than input, and thus it won't fit. This will cause the
         * library to return failure. gzip_compress() indicates this failure by returning original input size.
         * However in failure case, gzip_compress() simply copies data from src to dest buffer if s_len, d_len
         * parameters have the same value. Therefore to avoid unnecessary copying, dst_len = src-len - 1 is
         * being passed.
         * If return value of gzip_compress() equals original size, it'll be identified as error scenario and
         * original uncompressed bitmap will be written to the disk.
         */
        u_int64_t dest_size = gzip_compress(free_bitmap->bits, compressed_bitmap, size, size-1, COMPRESSION_LEVEL);

        if(stat(holemap, &sb)==0)
                exists = 1;
  
        if (exists) {
                bm = fopen(holemap, "r+b");
		if(!bm) {
			fprintf(stderr,"Error: cannot open holemap file %s: %s\n", holemap, strerror(errno));
                        free(compressed_bitmap);
			exit(-1);
		}
                fseek(bm, 0, size);
                nread = fread(&free_bitmap->bmhdr, sizeof(free_bitmap->bmhdr), 1, bm);
	} else {
		bm = fopen(holemap, "w+b");
		if(!bm) {
			fprintf(stderr,"Error: cannot create holemap file %s: %s\n", holemap, strerror(errno));
                        free(compressed_bitmap);
			exit(-1);
		}
        }

        if (dest_size != size) {
                /* compressed length < source length 
                 * i.e. compression was successful 
                 */
                free_bitmap->bmhdr.compressed_size = dest_size;
                free_bitmap->bmhdr.is_compressed = 1;
                fseek(bm, 0, SEEK_SET);
                bitmap_fwrite(&free_bitmap->bmhdr, sizeof(free_bitmap->bmhdr), 1, bm);
                bitmap_fwrite(&free_bitmap->mqhdr, sizeof(free_bitmap->mqhdr), 1, bm);
                fseek(bm, FC_BITMAP_BITMAP_OFFSET, SEEK_SET);
                /* write compressed bitmap */
                bitmap_fwrite(compressed_bitmap, dest_size, 1, bm);
        } else {
                /* compressed length = source length: this can happen only 
                 * in case of failure
                 */
                fseek(bm, 0, SEEK_SET);
                bitmap_fwrite(&free_bitmap->bmhdr, sizeof(free_bitmap->bmhdr), 1, bm);
                bitmap_fwrite(&free_bitmap->mqhdr, sizeof(free_bitmap->mqhdr), 1, bm);
                fseek(bm, FC_BITMAP_BITMAP_OFFSET, SEEK_SET);
                /* write uncompressed bitmap */
                bitmap_fwrite(free_bitmap->bits, size, 1, bm);
        }

        free(compressed_bitmap);
        if (fclose(bm)) {
                fprintf(stderr, "Error: unable to close file %s : %s\n", holemap, strerror(errno));
                exit(-1);
        }
}

/*
 * Read bitmap/holemap file from disk.
 * holemap files will be decompressed before populating ram_bitmap_t
 */
ram_bitmap_t *bitmap_read(const char *bitmap)
{
	size_t nread, compressed_size;
        int ret;
        unsigned char * compressed_bitmap = NULL;
	fc_bitmap_mq_hdr_t mqhdr;
	ram_bitmap_t *ram_bitmap = NULL;
        FILE *bm = fopen(bitmap, "r");
        
        if (!bm)
	        goto fail;

	/* get the size of the bitmap */
	fseek(bm, FC_BITMAP_MQ_HDR_OFFSET, SEEK_SET);
        nread = fread(&mqhdr, sizeof(mqhdr), 1, bm);
	if (nread != 1)
		goto fail;

	/* create the bitmap */
	if ((ram_bitmap = bitmap_create(mqhdr.vdisk_size_lbas*LBAS_SIZE,
					mqhdr.grain_size_lbas*LBAS_SIZE)) == NULL)
		goto fail;
	
        /*
	 * now that the properly sized bitmap is created, read it in
	 * first, read the headers
	 * then, read the bits
	 */
	fseek(bm, 0, SEEK_SET);
	nread = fread (&ram_bitmap->bmhdr, sizeof(ram_bitmap->bmhdr), 1, bm);
	if (nread != 1)
		goto fail;
	
        /*
	 * this is initialized by bitmap_create(), but still rewrite,
	 * just to make sure the header is exactly the same as on disk
	 */
	ram_bitmap->mqhdr = mqhdr;
	/* read in the bitmap bits */
        fseek(bm, FC_BITMAP_BITMAP_OFFSET, SEEK_SET);

        /* check if bitmap needs to be decompressed before storing*/
        if (ram_bitmap->bmhdr.is_compressed) {
                compressed_size = ram_bitmap->bmhdr.compressed_size;
                compressed_bitmap = (unsigned char *) malloc(compressed_size);
                nread = fread(compressed_bitmap, compressed_size, 1, bm);
                if (nread != 1)
                        goto fail;
                ret = gzip_decompress(compressed_bitmap, ram_bitmap->bits, compressed_size, 
                                ram_bitmap->mqhdr.bitmap_size_bytes, COMPRESSION_LEVEL);
                if (ret < 0) {
                        fprintf(stderr,"Error: holemap file decompression failed\n");
                        goto fail;
                }
                free(compressed_bitmap);
        } else {
                nread = fread(ram_bitmap->bits, ram_bitmap->mqhdr.bitmap_size_bytes, 1, bm);
                if (nread != 1)
                        goto fail;
        }
        fclose(bm);

	return ram_bitmap;
fail:
	perror("Failed to read bitmap");
	if (bm)
		fclose(bm);
	if (ram_bitmap)
		free(ram_bitmap);
        if (compressed_bitmap)
                free(compressed_bitmap);
	return (NULL);
}


/*
 * Produce a result bitmap which is a logical OR of the
 * left- and righ-hand-side bitmap arguments
 * the lhs and rhs arguments can be of different sizes,
 * but the result has to be of the largest size
 */
int bitmap_add(ram_bitmap_t *result, ram_bitmap_t *lhs, ram_bitmap_t *rhs)
{
        fc_bitmap_mq_hdr_t *hdr_res = &(result->mqhdr),
		*hdr_lhs = &(lhs->mqhdr), *hdr_rhs = &(rhs->mqhdr);
        unsigned char *bits_res = &(result->bits[0]), *bits_lhs = &(lhs->bits[0]),
		*bits_rhs = &(rhs->bits[0]), *bits_remainder = NULL;
        uint64_t i, min_size, max_size;

        /* compare grains and sizes */
        if (hdr_lhs->grain_size_lbas != hdr_rhs->grain_size_lbas ||
	    hdr_lhs->grain_size_lbas != hdr_res->grain_size_lbas) {
                fprintf(stderr, "different bitmap grain size detected,"
			" cannot add bitmaps\n");
                return (-1);
        }

        if (hdr_lhs->bitmap_size_bytes > hdr_rhs->bitmap_size_bytes) {
		min_size = hdr_rhs->bitmap_size_bytes;
		max_size = hdr_lhs->bitmap_size_bytes;
		bits_remainder = bits_lhs;
	} else {
		min_size = hdr_lhs->bitmap_size_bytes;
		max_size = hdr_rhs->bitmap_size_bytes;
		bits_remainder = bits_rhs;
	}

        if (max_size != hdr_res->bitmap_size_bytes) {
                fprintf(stderr, "resulting bitmap is of wrong byte size,"
			" cannot add bitmaps\n");
                return (-1);
        }

	/* OR the common parts of the bitmaps */
        for (i = 0; i < min_size; i++)
                bits_res[i] = bits_lhs[i] | bits_rhs[i];

	/* fill in the rest using the larger bitmap */
	for ( ; i < max_size; i++)
		bits_res[i] = bits_remainder[i];

        return (0);
}

/*
 * Produce a result bitmap which is a logical AND of the
 * left-hand-side bitmap and the inverse of the right-hand-size bitmap
 * We will require that the rhs bitmap is not larger than the lhs bitmap,
 * and the lhs bitmap is not larger than the lhs bitmap
 */
int bitmap_subtract(ram_bitmap_t *result, ram_bitmap_t *lhs, ram_bitmap_t *rhs)
{
        fc_bitmap_mq_hdr_t *hdr_res = &(result->mqhdr),
		*hdr_lhs = &(lhs->mqhdr), *hdr_rhs = &(rhs->mqhdr);
        unsigned char *bits_res = &(result->bits[0]), *bits_lhs = &(lhs->bits[0]),
		*bits_rhs = &(rhs->bits[0]);
        uint64_t i;

        /* compare grains and byte sizes */
        if (hdr_lhs->grain_size_lbas != hdr_rhs->grain_size_lbas ||
	    hdr_lhs->grain_size_lbas != hdr_res->grain_size_lbas) {
                fprintf(stderr, "different bitmap grain sizes detected,"
			" cannot subtract bitmaps\n");
                return (-1);
        }

        if (hdr_lhs->bitmap_size_bytes < hdr_rhs->bitmap_size_bytes ||
	    hdr_res->bitmap_size_bytes < hdr_lhs->bitmap_size_bytes) {
                fprintf(stderr, "bitmap sizes are incompatible,"
			" cannot subtract bitmaps\n");
                return (-1);
	}
		
	/* subtract up to the rhs size */
        for (i = 0; i < hdr_rhs->bitmap_size_bytes; i++)
                bits_res[i] = bits_lhs[i] & (~bits_rhs[i]);

	/* copy up to the lhs size */
        for ( ; i < hdr_lhs->bitmap_size_bytes; i++)
                bits_res[i] = bits_lhs[i];

        return (0);
}



/* assumes the string of length at least 9 is managed by the caller */
char *bitmap_show_bits(char *string, const char bits)
{
	/* print out bits 0-7 left to right */
	char *ptr;
	int i;
	for (i = 0, ptr = string; i < 8; i++, ptr++) {
		sprintf(ptr, "%d", (bits & (1 << i)) >> i);
	}
	string[8] = '\0';
	return string;
}


void bitmap_show(ram_bitmap_t *bitmap, uint64_t offset)
{
    uint64_t i, j, ngrains;

    if ((bitmap->mqhdr.bitmap_mq_magic[0] != ((FC_BITMAP_MQ_MAGIC >> 24) & 0xFF)) ||
	(bitmap->mqhdr.bitmap_mq_magic[1] != ((FC_BITMAP_MQ_MAGIC >> 16) & 0xFF)) ||
	(bitmap->mqhdr.bitmap_mq_magic[2] != ((FC_BITMAP_MQ_MAGIC >>  8) & 0xFF)) ||
	(bitmap->mqhdr.bitmap_mq_magic[3] != (FC_BITMAP_MQ_MAGIC & 0xFF))) {
	fprintf(stderr, "Invalid magic number in the bitmap mq header\n");
	exit(-1);
    }

    fprintf(stdout, "Bitmap header:\n");
    fprintf(stdout, "\tbitmap size: 0x%"PRIx64" grains\n", bitmap->mqhdr.bitmap_size_bytes*8);
    fprintf(stdout, "\tvdisk size: 0x%"PRIx64"\n", bitmap->mqhdr.vdisk_size_lbas*LBAS_SIZE);
    fprintf(stdout, "\tgrain size: 0x%"PRIx32"\n", bitmap->mqhdr.grain_size_lbas*LBAS_SIZE);

    if (offset != ~0ULL) {
	/* just find the grain and tell if it is set */
	uint64_t grain = offset / (bitmap->mqhdr.grain_size_lbas*LBAS_SIZE);
	fprintf(stdout,
		"bitmap offset 0x%"PRIx64" belongs to grain 0x%"PRIx64" that is %s\n",
		offset, grain, (bitmap->bits[grain/8] & (1 << (grain%8))) ? "set" : "cleared");
	return;
    }

    ngrains = bitmap->mqhdr.bitmap_size_bytes * 8;

    fprintf(stdout, "Bitmap bitset:");
    for (i = 0; i < bitmap->mqhdr.bitmap_size_bytes; i++) {
	char bit_string[9];
	if ((i % 8) == 0)
	    fprintf(stdout, "\n\t");
	fprintf(stdout, "%s ", bitmap_show_bits(bit_string, bitmap->bits[i]));
    }
    fprintf(stdout, "\n");

    fprintf(stdout, "Bitmap range list:\n");
    for (i = 0; i < ngrains; i = j) {
	uint64_t start, end;
	int iset = (bitmap->bits[i/8] & (1 << (i%8))) >> (i%8);
	/* find next cleared/set range */
	for (j = i; (j < ngrains); j++) {
	    int jset = (bitmap->bits[j/8] & (1 << (j%8))) >> (j%8);
	    if (jset != iset)
		break;
	}
	start = bitmap->mqhdr.grain_size_lbas*LBAS_SIZE*i;
	end = bitmap->mqhdr.grain_size_lbas*LBAS_SIZE*j;
	fprintf(stdout, "\tbitmap range: [0x%"PRIx64",0x%"PRIx64") is %s (0x%"PRIx64" grain%s)\n",
		start, end, (iset) ? "set" : "cleared", j - i, ((j - i) > 1) ? "s" : "");
    }

    return;
}


/*
 * return 0 if bitmap1 is a subset of bitmap2 (or equal to it),
 * and return -1 otherwise
 */
int bitmap_compare(ram_bitmap_t *bm1, ram_bitmap_t *bm2)
{
        fc_bitmap_mq_hdr_t *hdr1 = &(bm1->mqhdr), *hdr2 = &(bm2->mqhdr);
        unsigned char *bitmap1 = &(bm1->bits[0]), *bitmap2 = &(bm2->bits[0]);
        uint64_t i, missing_bits = 0, extra_bits = 0;

        /* compare headers */
        if (hdr1->grain_size_lbas != hdr2->grain_size_lbas) {
                fprintf(stderr, "different bitmap grain size (%d vs %d), "
                    "cannot compare bitmaps\n",
                    hdr1->grain_size_lbas, hdr2->grain_size_lbas);
                return (-1);
        }
        if (hdr1->bitmap_size_bytes > hdr2->bitmap_size_bytes) {
                uint64_t diff_first_byte =
                    hdr2->bitmap_size_bytes*8*hdr2->grain_size_lbas*LBAS_SIZE,
                    diff_last_byte =
                    hdr1->bitmap_size_bytes*8*hdr1->grain_size_lbas*LBAS_SIZE;
                fprintf(stderr, "unexpected differences found in byte range "
                    "[0x%"PRIx64",0x%"PRIx64") (all data different) \n",
                    diff_first_byte, diff_last_byte);
                return (-1);
        }

        for (i = 0; i < hdr1->bitmap_size_bytes; i++) {
		char bm_byte[2][9];
                uint8_t mask = (uint8_t)(bitmap1[i] & ~bitmap2[i]);
		uint64_t diff_first_byte =
			i*8*hdr1->grain_size_lbas*LBAS_SIZE,
			diff_last_byte =
			diff_first_byte + 8*hdr1->grain_size_lbas*LBAS_SIZE;
		uint32_t grain_bytes = hdr1->grain_size_lbas*LBAS_SIZE;

                /*
                 * are there some bits in bitmap1[i] that are not
                 * present in bitmap2[i] ?
                 */
		mask = (uint8_t)(bitmap1[i] & ~bitmap2[i]);
                if (mask) {
                        if (verbosity) {
                                fprintf(stderr, "missing bits found in byte range "
                                    "[0x%"PRIx64",0x%"PRIx64"), grain size 0x%x bytes, "
                                    "range diffs (gain units) %s vs %s\n",
                                    diff_first_byte, diff_last_byte, grain_bytes,
				    bitmap_show_bits(bm_byte[0], bitmap1[i]),
				    bitmap_show_bits(bm_byte[1], bitmap2[i]));
                        }
                        missing_bits = 1;
                }
                /*
                 * are there some bits in bitmap2[i] that are not
                 * present in bitmap1[i] (extra bits)?
                 */
                mask = (uint8_t)(bitmap2[i] & ~bitmap1[i]);
                if (mask) {
                        if (verbosity) {
                                fprintf(stderr, "extra bits found in byte range "
                                    "[0x%"PRIx64",0x%"PRIx64"), grain size 0x%x bytes, "
                                    "range diffs (grain units) %s vs %s\n",
                                    diff_first_byte, diff_last_byte, grain_bytes,
				    bitmap_show_bits(bm_byte[0], bitmap1[i]),
				    bitmap_show_bits(bm_byte[1], bitmap2[i]));
                        }
                        extra_bits = 1;
                }
        }

        if (missing_bits) {
                fprintf(stderr, "bitmap is missing some bits\n");
                return (-1);
        }

        if (extra_bits)
                fprintf(stderr, "bitmap has some extra bits\n");

        /* bitmap1 is a subset of (or equal to) bitmap2 */
        return (0);
}

uint64_t bitmap_get_bitcount(ram_bitmap_t *bm)
{
        const uint64_t bitmap_size_bytes = bm->mqhdr.bitmap_size_bytes;
        const unsigned char *bitmap = &(bm->bits[0]);
        uint64_t i, j, bitcount;

        /* walk the bitmap and count the bits */
        for (bitcount = 0, i = 0; i < bitmap_size_bytes; i++) {
		if (bitmap[i] == 0)
			continue;
                for (j = 0; j < 8; j++) {
                        if (bitmap[i] & (1 << j))
                                bitcount++;
                }
        }

        return (bitcount);
}

int bitmap_get_bit(ram_bitmap_t *bm, uint64_t byte_offset)
{
        const unsigned char *bitmap = &(bm->bits[0]);
        uint64_t grainsize = bm->mqhdr.grain_size_lbas * LBAS_SIZE;
        uint64_t abs_bit = byte_offset / grainsize;
        uint64_t byte = abs_bit / 8, bit = abs_bit % 8;
    
        if (byte >= bm->mqhdr.bitmap_size_bytes)
                return -1;

        return ((bitmap[byte] & (1 << bit)) >> bit);
}
