Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jeff King
On Wed, Jan 22, 2014 at 06:05:36PM -0800, Jonathan Nieder wrote:

 Jeff King wrote:
 
  EWAH is a word-aligned compressed variant of a bitset (i.e. a data
  structure that acts as a 0-indexed boolean array for many entries).
 
 I suspect that for some callers it's not word-aligned.

Yes, the mmap'd buffers aren't necessarily word-aligned. I don't think
we can fix that easily without changing the on-disk format (which comes
from JGit anyway). However, since we are memcpying the bulk of the data
into a newly allocated buffer (which must be aligned), we can do that
first, and then fix the endian-ness in place.

The only SPARC machine I have access to is running Solaris, but after
some slight wrestling with the BYTE_ORDER macros, I managed to get it to
compile and reproduced the bus error.

Here's a patch series (on top of jk/pack-bitmap, naturally) that lets
t5310 pass there. I assume the ARM problem is the same, though seeing
the failure in realloc() is unexpected. Can you try it on both your
platforms with these patches?

  [1/2]: compat: move unaligned helpers to bswap.h
  [2/2]: ewah: support platforms that require aligned reads

 Hopefully it's possible to get the alignment right in the caller
 and tweak the signature to require that instead of using unaligned
 reads like this.  There's still something wrong after this patch ---
 the new result is a NULL pointer dereference in t5310.7 enumerate
 --objects (full bitmap).

After my patches, t5310 runs fine for me. I didn't try your patch, but
mine are similar. Let me know if you still see the problem (there may
simply be a bug in yours, but I didn't see it).

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jonathan Nieder
Jeff King wrote:

 Here's a patch series (on top of jk/pack-bitmap, naturally) that lets
 t5310 pass there. I assume the ARM problem is the same, though seeing
 the failure in realloc() is unexpected. Can you try it on both your
 platforms with these patches?

Thanks.  Trying it out now.

[...]
 Hopefully it's possible to get the alignment right in the caller
 and tweak the signature to require that instead of using unaligned
 reads like this.  There's still something wrong after this patch ---
 the new result is a NULL pointer dereference in t5310.7 enumerate
 --objects (full bitmap).

 After my patches, t5310 runs fine for me. I didn't try your patch, but
 mine are similar. Let me know if you still see the problem (there may
 simply be a bug in yours, but I didn't see it).

I had left out a cast to unsigned, producing an overflow.

My main worry about the patches is that they will probably run into
an analagous problem to the one that v1.7.12-rc0~1^2~2 (block-sha1:
avoid pointer conversion that violates alignment constraints,
2012-07-22) solved.  By casting the pointer to (uint32_t *) we are
telling the compiler it is 32-bit aligned (C99 section 6.3.2.3).

Thanks,
Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jeff King
On Thu, Jan 23, 2014 at 11:52:06AM -0800, Jonathan Nieder wrote:

  After my patches, t5310 runs fine for me. I didn't try your patch, but
  mine are similar. Let me know if you still see the problem (there may
  simply be a bug in yours, but I didn't see it).
 
 I had left out a cast to unsigned, producing an overflow.
 
 My main worry about the patches is that they will probably run into
 an analagous problem to the one that v1.7.12-rc0~1^2~2 (block-sha1:
 avoid pointer conversion that violates alignment constraints,
 2012-07-22) solved.  By casting the pointer to (uint32_t *) we are
 telling the compiler it is 32-bit aligned (C99 section 6.3.2.3).

Yeah, maybe. We go via memcpy, which takes a void *, so that part is
good. However, the new code looks like:

  foo = align_ntohl(*(uint32_t *)ptr);

I think this probably works in practice because align_ntohl is inlined,
and any sane compiler will never actually load the variable. If we
change the signature of align_ntohl, we can do this:

  uint32_t align_ntohl(void *ptr)
  {
  uint32_t x;
  memcpy(x, ptr, sizeof(x));
  return ntohl(x);
  }

  ...

  foo = align_ntohl(ptr);

The memcpy solution is taken from read-cache.c, but as we noted, it
probably hasn't been used a lot. The blk_sha1 get_be may be faster, as
it converts as it reads. However, the bulk of the data is copied via
a single memcpy and then modified in place. I don't know if that would
be faster or not (for a big-endian system it probably is, since we can
omit the modification loop entirely).

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jonathan Nieder
Jeff King wrote:
 On Thu, Jan 23, 2014 at 11:52:06AM -0800, Jonathan Nieder wrote:

 My main worry about the patches is that they will probably run into
 an analagous problem to the one that v1.7.12-rc0~1^2~2
[...]
 I think this probably works in practice because align_ntohl is inlined,
 and any sane compiler will never actually load the variable.

I don't think that's safe to rely on.  The example named above didn't
pose any problems except on one platform.  All the relevant functions
were static and easy to inline.  GCC just followed the standard
literally and chose to break by reading one word at a time, just like
in this case it could break e.g. by copying one word at a time in
__builtin_memcpy (which seems perfectly reasonable to me ---
optimization involves a lot of constraint solving, and if you can't
trust your constraints then there's not much you can do).
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Shawn Pearce
On Thu, Jan 23, 2014 at 10:33 AM, Jeff King p...@peff.net wrote:
 On Wed, Jan 22, 2014 at 06:05:36PM -0800, Jonathan Nieder wrote:

 Jeff King wrote:

  EWAH is a word-aligned compressed variant of a bitset (i.e. a data
  structure that acts as a 0-indexed boolean array for many entries).

 I suspect that for some callers it's not word-aligned.

 Yes, the mmap'd buffers aren't necessarily word-aligned. I don't think
 we can fix that easily without changing the on-disk format (which comes
 from JGit anyway).

Ouch, sorry about that. JGit doesn't mmap the file so we didn't think
about the impact of words not being aligned. I should have caught
that, but I didn't.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jeff King
On Thu, Jan 23, 2014 at 12:12:23PM -0800, Jonathan Nieder wrote:

 Jeff King wrote:
  On Thu, Jan 23, 2014 at 11:52:06AM -0800, Jonathan Nieder wrote:
 
  My main worry about the patches is that they will probably run into
  an analagous problem to the one that v1.7.12-rc0~1^2~2
 [...]
  I think this probably works in practice because align_ntohl is inlined,
  and any sane compiler will never actually load the variable.
 
 I don't think that's safe to rely on.  The example named above didn't
 pose any problems except on one platform.  All the relevant functions
 were static and easy to inline.  GCC just followed the standard
 literally and chose to break by reading one word at a time, just like
 in this case it could break e.g. by copying one word at a time in
 __builtin_memcpy (which seems perfectly reasonable to me ---
 optimization involves a lot of constraint solving, and if you can't
 trust your constraints then there's not much you can do).

I wasn't disagreeing with you. I was guessing at why it did not fail out
of the box when I tested it.  What do you think of the alternative I
posted?

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jonathan Nieder
Jeff King wrote:

   [1/2]: compat: move unaligned helpers to bswap.h
   [2/2]: ewah: support platforms that require aligned reads

After setting NEEDS_ALIGNED_ACCESS,
Tested-by: Jonathan Nieder jrnie...@gmail.com # ARMv5
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jonathan Nieder
Jeff King wrote:

  If we
 change the signature of align_ntohl, we can do this:

   uint32_t align_ntohl(void *ptr)
   {
   uint32_t x;
   memcpy(x, ptr, sizeof(x));
   return ntohl(x);
   }

   ...

   foo = align_ntohl(ptr);

 The memcpy solution is taken from read-cache.c, but as we noted, it
 probably hasn't been used a lot. The blk_sha1 get_be may be faster, as
 it converts as it reads.

I doubt there's much difference either way, especially after an
optimizer gets its hands on it.  According to [1] ARM has no fast
byte swap instruction so with -O0 the byte-at-a-time implementation is
probably faster there.  I can try a performance test if you like.

Jonathan

[1] http://thread.gmane.org/gmane.comp.version-control.git/125737
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jeff King
On Thu, Jan 23, 2014 at 12:14:03PM -0800, Shawn Pearce wrote:

  Yes, the mmap'd buffers aren't necessarily word-aligned. I don't think
  we can fix that easily without changing the on-disk format (which comes
  from JGit anyway).
 
 Ouch, sorry about that. JGit doesn't mmap the file so we didn't think
 about the impact of words not being aligned. I should have caught
 that, but I didn't.

Looking over the format, I think the only thing preventing 4-byte
alignment is the 1-byte XOR-offset and 1-byte flags field for each
bitmap. If we ever have a v2, we could pad the sum of those out to 4
bytes. Is 4-byte alignment enough? We do treat the actual data as 64-bit
integers. I wonder if that would have problems on Sparc64, for example.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jeff King
On Thu, Jan 23, 2014 at 12:23:42PM -0800, Jonathan Nieder wrote:

  The memcpy solution is taken from read-cache.c, but as we noted, it
  probably hasn't been used a lot. The blk_sha1 get_be may be faster, as
  it converts as it reads.
 
 I doubt there's much difference either way, especially after an
 optimizer gets its hands on it.  According to [1] ARM has no fast
 byte swap instruction so with -O0 the byte-at-a-time implementation is
 probably faster there.  I can try a performance test if you like.

If you're curious and have time, go ahead and benchmark what I posted
against what you posted (with your fix). But you'll probably need a big
repo like the kernel to notice anything.

But I don't mind that much if we just use the memcpy trick for now. It's
nice and obvious, and we can always change it later if somebody has
numbers (I doubt it will be all that noticeable anyway; this isn't
nearly as tight a loop as the BLK_SHA1 code).

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jeff King
On Thu, Jan 23, 2014 at 03:03:11PM -0500, Jeff King wrote:

  My main worry about the patches is that they will probably run into
  an analagous problem to the one that v1.7.12-rc0~1^2~2 (block-sha1:
  avoid pointer conversion that violates alignment constraints,
  2012-07-22) solved.  By casting the pointer to (uint32_t *) we are
  telling the compiler it is 32-bit aligned (C99 section 6.3.2.3).
 
 Yeah, maybe. We go via memcpy, which takes a void *, so that part is
 good. However, the new code looks like:
 
   foo = align_ntohl(*(uint32_t *)ptr);
 
 I think this probably works in practice because align_ntohl is inlined,
 and any sane compiler will never actually load the variable. If we
 change the signature of align_ntohl, we can do this:

Actually, it is a little trickier than that. We actually take the
address in the macro. So even without inlining, we end up casting to
void. I still think this:

   uint32_t align_ntohl(void *ptr)
   {
   uint32_t x;
   memcpy(x, ptr, sizeof(x));
   return ntohl(x);
   }

is a little more obvious, though. It does mean that everybody has to
pass a pointer, though, and on platforms where non-aligned reads are OK,
we do the cast ourselves. That means that:

  foo = align_ntohl(bar);

will not be able to do any type-checking for bar (say, when we are
pulling bar straight out of a packed struct). I don't know how much
we care.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread brian m. carlson
On Thu, Jan 23, 2014 at 03:26:45PM -0500, Jeff King wrote:
 Looking over the format, I think the only thing preventing 4-byte
 alignment is the 1-byte XOR-offset and 1-byte flags field for each
 bitmap. If we ever have a v2, we could pad the sum of those out to 4
 bytes. Is 4-byte alignment enough? We do treat the actual data as 64-bit
 integers. I wonder if that would have problems on Sparc64, for example.

Yes, it will.  SPARC requires all loads be naturally aligned (4-byte to
an address that's a multiple of 4, 8-byte to a multiple of 8, and so
on).  In general, architectures that do not support unaligned access
require natural alignment for all quantities.

Also, even on architectures where the kernel can fix these alignment
issues up, the cost of doing so is a two context switches (in and out of
the kernel), servicing the trap, two loads, some shifts and rotates, and
a kernel message, so many people disable alignment fixups.  I know it
made things extremely slow on Alpha.  ARM is even more fun since if you
don't take the trap, it loads the data rotated, so the load happens, it
just silently returns the wrong data.

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only
OpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187


signature.asc
Description: Digital signature


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jeff King
On Thu, Jan 23, 2014 at 09:53:26PM +, brian m. carlson wrote:

 On Thu, Jan 23, 2014 at 03:26:45PM -0500, Jeff King wrote:
  Looking over the format, I think the only thing preventing 4-byte
  alignment is the 1-byte XOR-offset and 1-byte flags field for each
  bitmap. If we ever have a v2, we could pad the sum of those out to 4
  bytes. Is 4-byte alignment enough? We do treat the actual data as 64-bit
  integers. I wonder if that would have problems on Sparc64, for example.
 
 Yes, it will.  SPARC requires all loads be naturally aligned (4-byte to
 an address that's a multiple of 4, 8-byte to a multiple of 8, and so
 on).  In general, architectures that do not support unaligned access
 require natural alignment for all quantities.

In that case, I think we cannot even blame Shawn. The ewah serialization
format itself (which JGit inherited from the javaewah library) has 8
bytes of header and 4 bytes of trailer. So packed serialized ewahs
wouldn't be 8-byte aligned (though of course he could have added his own
padding to each when we have a sequence of them).

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jonathan Nieder
Jeff King wrote:
 On Thu, Jan 23, 2014 at 09:53:26PM +, brian m. carlson wrote:

 Yes, it will.  SPARC requires all loads be naturally aligned (4-byte to
 an address that's a multiple of 4, 8-byte to a multiple of 8, and so
 on).  In general, architectures that do not support unaligned access
 require natural alignment for all quantities.

 In that case, I think we cannot even blame Shawn. The ewah serialization
 format itself (which JGit inherited from the javaewah library) has 8
 bytes of header and 4 bytes of trailer. So packed serialized ewahs
 wouldn't be 8-byte aligned

I don't think that's a big issue.  A pair of 4-byte reads would not be
too slow.

Even on x86, aligned reads are supposed to be faster than unaligned
reads (though I haven't looked at benchmarks recently).
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jeff King
On Thu, Jan 23, 2014 at 02:17:55PM -0800, Jonathan Nieder wrote:

 Jeff King wrote:
  On Thu, Jan 23, 2014 at 09:53:26PM +, brian m. carlson wrote:
 
  Yes, it will.  SPARC requires all loads be naturally aligned (4-byte to
  an address that's a multiple of 4, 8-byte to a multiple of 8, and so
  on).  In general, architectures that do not support unaligned access
  require natural alignment for all quantities.
 
  In that case, I think we cannot even blame Shawn. The ewah serialization
  format itself (which JGit inherited from the javaewah library) has 8
  bytes of header and 4 bytes of trailer. So packed serialized ewahs
  wouldn't be 8-byte aligned
 
 I don't think that's a big issue.  A pair of 4-byte reads would not be
 too slow.

The header is actually two separate 4-byte values, so that's fine. But
between the header and trailer are a series of 8-byte data values, and
that is what we need the 8-byte alignment for. So the _first_ ewah's
data is 8-byte aligned, but then it offsets the alignment with a single
4-byte trailer. So the next ewah, if they are packed in a sequence, is
will have its data misaligned.

You could solve it by putting an empty 4-byte pad at the end of each
ewah (and of course making sure the first one is 8-byte aligned).

Anyway, this is all academic until we are designing bitmap v2, which I
do not plan on doing anytime soon.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-23 Thread Jonathan Nieder
Jeff King wrote:
 On Thu, Jan 23, 2014 at 02:17:55PM -0800, Jonathan Nieder wrote:

 I don't think that's a big issue.  A pair of 4-byte reads would not be
 too slow.

 The header is actually two separate 4-byte values, so that's fine. But
 between the header and trailer are a series of 8-byte data values, and
 that is what we need the 8-byte alignment for.

Sorry for the lack of clarity.  What I meant is that a 4-byte aligned
8-byte value can be read using a pair of 4-byte reads, which is less
of a performance issue than a completely unaligned value.

[...]
 Anyway, this is all academic until we are designing bitmap v2, which I
 do not plan on doing anytime soon.

Sure, fair enough. :)

Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 08/23] ewah: compressed bitmap implementation

2014-01-22 Thread Jonathan Nieder
Hi,

Jeff King wrote:

 EWAH is a word-aligned compressed variant of a bitset (i.e. a data
 structure that acts as a 0-indexed boolean array for many entries).

I suspect that for some callers it's not word-aligned.

Without the following squashed in, commits 212f2ffb and later fail t5310
on some machines[1].

On ARMv5:

expecting success: 
git rev-list --test-bitmap HEAD

*** Error in `/«PKGBUILDDIR»/git': realloc(): invalid pointer: 
0x008728b0 ***
Aborted
not ok 3 - rev-list --test-bitmap verifies bitmaps

On sparc:

expecting success: 
git rev-list --test-bitmap HEAD

Bus error
not ok 3 - rev-list --test-bitmap verifies bitmaps

Hopefully it's possible to get the alignment right in the caller
and tweak the signature to require that instead of using unaligned
reads like this.  There's still something wrong after this patch ---
the new result is a NULL pointer dereference in t5310.7 enumerate
--objects (full bitmap).

  (gdb) run
  Starting program: /home/jrnieder/src/git/git rev-list --objects 
--use-bitmap-index HEAD
  [Thread debugging using libthread_db enabled]
  Using host libthread_db library /lib/sparc-linux-gnu/libthread_db.so.1.
  537ea4d3eb79c95f602873b1167c480006d2ac2d
[...]
  ec635144f60048986bc560c5576355344005e6e7

  Program received signal SIGSEGV, Segmentation fault.
  0x001321c0 in sha1_to_hex (sha1=0x0) at hex.c:68
  68  unsigned int val = *sha1++;
  (gdb) bt
  #0  0x001321c0 in sha1_to_hex (sha1=0x0) at hex.c:68
  #1  0x000b839c in show_object_fast (sha1=0x0, type=OBJ_TREE, exclude=0, 
name_hash=0, found_pack=0x2b8480, found_offset=4338) at builtin/rev-list.c:270
  #2  0x00158abc in show_objects_for_type (objects=0x2b2498, 
type_filter=0x2b0fb0, object_type=OBJ_TREE, show_reach=0xb834c 
show_object_fast) at pack-bitmap.c:640
  #3  0x001592d0 in traverse_bitmap_commit_list (show_reachable=0xb834c 
show_object_fast) at pack-bitmap.c:818
  #4  0x000b894c in cmd_rev_list (argc=2, argv=0xd688, prefix=0x0) at 
builtin/rev-list.c:369
  #5  0x00014024 in run_builtin (p=0x256e38 commands+1020, argc=4, 
argv=0xd688) at git.c:314
  #6  0x00014330 in handle_builtin (argc=4, argv=0xd688) at git.c:487
  #7  0x000144a8 in run_argv (argcp=0xd5ec, argv=0xd5a0) at git.c:533
  #8  0x000146fc in main (argc=4, av=0xd684) at git.c:616
  (gdb) frame 2
  #2  0x00158abc in show_objects_for_type (objects=0x2b2498, 
type_filter=0x2b0fb0, object_type=OBJ_TREE, show_reach=0xb834c 
show_object_fast) at pack-bitmap.c:640
  640 show_reach(sha1, object_type, 0, hash, 
bitmap_git.pack, entry-offset);
  (gdb) p entry-nr
  $1 = 4294967295

Line numbers are in the context of 8e6341d9.  Ideas?

[1] ARMv5 and sparc:
https://buildd.debian.org/status/logs.php?pkg=gitsuite=experimental

diff --git a/ewah/ewah_io.c b/ewah/ewah_io.c
index aed0da6..696a8ec 100644
--- a/ewah/ewah_io.c
+++ b/ewah/ewah_io.c
@@ -110,25 +110,38 @@ int ewah_serialize(struct ewah_bitmap *self, int fd)
return ewah_serialize_to(self, write_helper, (void *)(intptr_t)fd);
 }
 
+#define get_be32(p) ( \
+   (*((unsigned char *)(p) + 0)  24) | \
+   (*((unsigned char *)(p) + 1)  16) | \
+   (*((unsigned char *)(p) + 2)   8) | \
+   (*((unsigned char *)(p) + 3)   0) )
+
+#define get_be64(p) ( \
+   ((uint64_t) get_be32(p)  32) | \
+   get_be32((unsigned char *)(p) + 4) )
+
 int ewah_read_mmap(struct ewah_bitmap *self, void *map, size_t len)
 {
-   uint32_t *read32 = map;
-   eword_t *read64;
+   unsigned char *p = map;
size_t i;
 
-   self-bit_size = ntohl(*read32++);
-   self-buffer_size = self-alloc_size = ntohl(*read32++);
+   self-bit_size = get_be32(p);
+   p += 4;
+   self-buffer_size = self-alloc_size = get_be32(p);
+   p += 4;
self-buffer = ewah_realloc(self-buffer,
self-alloc_size * sizeof(eword_t));
 
if (!self-buffer)
return -1;
 
-   for (i = 0, read64 = (void *)read32; i  self-buffer_size; ++i)
-   self-buffer[i] = ntohll(*read64++);
+   for (i = 0; i  self-buffer_size; ++i) {
+   self-buffer[i] = get_be64(p);
+   p += 8;
+   }
 
-   read32 = (void *)read64;
-   self-rlw = self-buffer + ntohl(*read32++);
+   self-rlw = self-buffer + get_be32(p);
+   p += 4;
 
return (3 * 4) + (self-buffer_size * 8);
 }

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 08/23] ewah: compressed bitmap implementation

2013-12-21 Thread Jeff King
From: Vicent Marti tan...@gmail.com

EWAH is a word-aligned compressed variant of a bitset (i.e. a data
structure that acts as a 0-indexed boolean array for many entries).

It uses a 64-bit run-length encoding (RLE) compression scheme,
trading some compression for better processing speed.

The goal of this word-aligned implementation is not to achieve
the best compression, but rather to improve query processing time.
As it stands right now, this EWAH implementation will always be more
efficient storage-wise than its uncompressed alternative.

EWAH arrays will be used as the on-disk format to store reachability
bitmaps for all objects in a repository while keeping reasonable sizes,
in the same way that JGit does.

This EWAH implementation is a mostly straightforward port of the
original `javaewah` library that JGit currently uses. The library is
self-contained and has been embedded whole (4 files) inside the `ewah`
folder to ease redistribution.

The library is re-licensed under the GPLv2 with the permission of Daniel
Lemire, the original author. The source code for the C version can
be found on GitHub:

https://github.com/vmg/libewok

The original Java implementation can also be found on GitHub:

https://github.com/lemire/javaewah

Signed-off-by: Vicent Marti tan...@gmail.com
Signed-off-by: Jeff King p...@peff.net
---
 Makefile   |  11 +-
 ewah/bitmap.c  | 221 
 ewah/ewah_bitmap.c | 726 +
 ewah/ewah_io.c | 193 ++
 ewah/ewah_rlw.c| 115 +
 ewah/ewok.h| 235 +
 ewah/ewok_rlw.h| 114 +
 7 files changed, 1613 insertions(+), 2 deletions(-)
 create mode 100644 ewah/bitmap.c
 create mode 100644 ewah/ewah_bitmap.c
 create mode 100644 ewah/ewah_io.c
 create mode 100644 ewah/ewah_rlw.c
 create mode 100644 ewah/ewok.h
 create mode 100644 ewah/ewok_rlw.h

diff --git a/Makefile b/Makefile
index 48ff0bd..64a1ed7 100644
--- a/Makefile
+++ b/Makefile
@@ -667,6 +667,8 @@ LIB_H += diff.h
 LIB_H += diffcore.h
 LIB_H += dir.h
 LIB_H += exec_cmd.h
+LIB_H += ewah/ewok.h
+LIB_H += ewah/ewok_rlw.h
 LIB_H += fetch-pack.h
 LIB_H += fmt-merge-msg.h
 LIB_H += fsck.h
@@ -800,6 +802,10 @@ LIB_OBJS += dir.o
 LIB_OBJS += editor.o
 LIB_OBJS += entry.o
 LIB_OBJS += environment.o
+LIB_OBJS += ewah/bitmap.o
+LIB_OBJS += ewah/ewah_bitmap.o
+LIB_OBJS += ewah/ewah_io.o
+LIB_OBJS += ewah/ewah_rlw.o
 LIB_OBJS += exec_cmd.o
 LIB_OBJS += fetch-pack.o
 LIB_OBJS += fsck.o
@@ -2474,8 +2480,9 @@ profile-clean:
$(RM) $(addsuffix *.gcno,$(addprefix $(PROFILE_DIR)/, $(object_dirs)))
 
 clean: profile-clean coverage-clean
-   $(RM) *.o *.res block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o 
xdiff/*.o vcs-svn/*.o \
-   builtin/*.o $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB)
+   $(RM) *.o *.res block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o
+   $(RM) xdiff/*.o vcs-svn/*.o ewah/*.o builtin/*.o
+   $(RM) $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB)
$(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X
$(RM) $(TEST_PROGRAMS) $(NO_INSTALL)
$(RM) -r bin-wrappers $(dep_dirs)
diff --git a/ewah/bitmap.c b/ewah/bitmap.c
new file mode 100644
index 000..710e58c
--- /dev/null
+++ b/ewah/bitmap.c
@@ -0,0 +1,221 @@
+/**
+ * Copyright 2013, GitHub, Inc
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon,
+ * David McIntosh, Robert Becho, Google Inc. and Veronika Zenz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA.
+ */
+#include git-compat-util.h
+#include ewok.h
+
+#define MASK(x) ((eword_t)1  (x % BITS_IN_WORD))
+#define BLOCK(x) (x / BITS_IN_WORD)
+
+struct bitmap *bitmap_new(void)
+{
+   struct bitmap *bitmap = ewah_malloc(sizeof(struct bitmap));
+   bitmap-words = ewah_calloc(32, sizeof(eword_t));
+   bitmap-word_alloc = 32;
+   return bitmap;
+}
+
+void bitmap_set(struct bitmap *self, size_t pos)
+{
+   size_t block = BLOCK(pos);
+
+   if (block = self-word_alloc) {
+   size_t old_size = self-word_alloc;
+   self-word_alloc = block * 2;
+   self-words = ewah_realloc(self-words,
+   self-word_alloc * sizeof(eword_t));
+
+   memset(self-words + old_size, 0x0,
+