On 08/01/2015 22:21, John Snow wrote: > Why are the conversions to little endian, though? Shouldn't we be > serializing to a Big Endian format?
Because reading two 32-bit little-endian longs or a 64-bit little-endian long gives the same value. This is not true for big-endian. Take the following two 32-bit values: 0x04030201 0x08070605 representing offsets 0 and 32 in the bitmap. Parse them back as one 64-bit little endian value: 0x0807060504030201 = 0x04030201 + 0x08070605 * 2^32 Now parse them as as one 64-bit big endian value: 0x0403020108070605 => 0x08070605 + 0x04030201 * 2^32 so the values are swapped. >> +void hbitmap_restore_data(HBitmap *hb, uint8_t *buf, >> + uint64_t start, uint64_t count) >> +{ >> + uint64_t last = start + count - 1; >> + unsigned long *in = (unsigned long *)buf; >> + >> + if (count == 0) { >> + return; >> + } >> + >> + start = (start >> hb->granularity) >> BITS_PER_LEVEL; >> + last = (last >> hb->granularity) >> BITS_PER_LEVEL; >> + count = last - start + 1; >> + >> +#ifdef __BIG_ENDIAN_BITFIELD >> + for (i = start; i <= last; ++i) { >> + hb->levels[HBITMAP_LEVELS - 1][i] = >> + (BITS_PER_LONG == 32 ? be32_to_cpu(in[i]) : >> be64_to_cpu(in[i])); >> + } >> +#else >> + memcpy(&hb->levels[HBITMAP_LEVELS - 1][start], in, >> + count * sizeof(unsigned long)); >> +#endif >> +} >> + > > ...? We're storing as LE but restoring from BE? I'm confused. > > I'm also not clear on the __BIG_ENDIAN_BITFIELD macro. Why do we want to > pack differently based on how C-bitfields are packed by the compiler? I > don't think that has any impact on how longs are stored (always in the > host native format.) I agree. Paolo