Subject: [PATCH v2 00/10] Xdiff cleanup part2

From: "Ezekiel Newren via GitGitGadget" <[email-masked]>
Date: Wed, 29 Oct 2025 22:19:38 +0000

Changes in v2:

 * Added documentation about unambiguous types and FFI
 * Addressed comments on the mailing list

Original cover letter below:
============================

Maintainer note: This patch series builds on top of en/xdiff-cleanup and
am/xdiff-hash-tweak (both of which are now in master).

The primary goal of this patch series is to convert every field's type in
xrecord_t and xdfile_t to be unambiguous, in preparation to make it more
Rust FFI friendly. Additionally the ha field in xrecord_t is split into
line_hash and minimal_perfect hash.

The order of some of the fields has changed as called out by the commit
messages.

Before:

typedef struct s_xrecord {
	char const *ptr;
	long size;
	unsigned long ha;
} xrecord_t;

typedef struct s_xdfile {
	xrecord_t *recs;
	long nrec;
	long dstart, dend;
	bool *changed;
	long *rindex;
	long nreff;
} xdfile_t;

After part 2

typedef struct s_xrecord {
	uint8_t const *ptr;
	size_t size;
	uint64_t line_hash;
	size_t minimal_perfect_hash;
} xrecord_t;

typedef struct s_xdfile {
	xrecord_t *recs;
	size_t nrec;
	bool *changed;
	size_t *reference_index;
	size_t nreff;
	ssize_t dstart, dend;
} xdfile_t;

Ezekiel Newren (10):
  doc: define unambiguous type mappings across C and Rust
  xdiff: use ssize_t for dstart/dend, make them last in xdfile_t
  xdiff: make xrecord_t.ptr a uint8_t instead of char
  xdiff: use size_t for xrecord_t.size
  xdiff: use unambiguous types in xdl_hash_record()
  xdiff: split xrecord_t.ha into line_hash and minimal_perfect_hash
  xdiff: make xdfile_t.nrec a size_t instead of long
  xdiff: make xdfile_t.nreff a size_t instead of long
  xdiff: change rindex from long to size_t in xdfile_t
  xdiff: rename rindex -> reference_index

 .../technical/unambiguous-types.adoc          | 229 ++++++++++++++++++
 xdiff-interface.c                             |   2 +-
 xdiff/xdiffi.c                                |  29 ++-
 xdiff/xemit.c                                 |  28 +--
 xdiff/xhistogram.c                            |   4 +-
 xdiff/xmerge.c                                |  30 +--
 xdiff/xpatience.c                             |  14 +-
 xdiff/xprepare.c                              |  58 ++---
 xdiff/xtypes.h                                |  15 +-
 xdiff/xutils.c                                |  32 +--
 xdiff/xutils.h                                |   6 +-
 11 files changed, 338 insertions(+), 109 deletions(-)
 create mode 100644 Documentation/technical/unambiguous-types.adoc

base-commit: 143f58ef7535f8f8a80d810768a18bdf3807de26
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2070%2Fezekielnewren%2Fxdiff_cleanup_part2-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2070/ezekielnewren/xdiff_cleanup_part2-v2
Pull-Request: https://github.com/git/git/pull/2070

Range-diff vs v1:

  -:  ---------- >  1:  88133848d1 doc: define unambiguous type mappings across C and Rust
  1:  1fa9a7d7d1 !  2:  9197903add xdiff: use ssize_t for dstart/dend, make them last in xdfile_t
     @@ xdiff/xtypes.h: typedef struct s_xrecord {
       	bool *changed;
       	long *rindex;
       	long nreff;
     -+	ssize_t dstart, dend;
     ++	ptrdiff_t dstart, dend;
       } xdfile_t;
       
       typedef struct s_xdfenv {
  2:  7b9e8961d4 !  3:  46bc1b3e25 xdiff: make xrecord_t.ptr a uint8_t instead of char
     @@ Commit message
          xdiff: make xrecord_t.ptr a uint8_t instead of char
      
          Rust uses u8 to refer to bytes in memory. Since xrecord_t.ptr is also
     -    referring to bytes in memory, rather than unicode code points, use
     +    referring to bytes in memory, rather than Unicode code points, use
          uint8_t instead of char.
      
     +    Every usage of this field was inspected and cast to char*, or similar,
     +    to avoid signedness warnings/errors from the compiler. Casting was used
     +    so that the whole of xdiff doesn't need to be refactored in order to
     +    change the type of this field.
     +
          Signed-off-by: Ezekiel Newren <[email-masked]>
      
       ## xdiff/xdiffi.c ##
  3:  ae15ed7121 =  4:  07e28aad3b xdiff: use size_t for xrecord_t.size
  4:  7fcd83c990 !  5:  1ade7d8165 xdiff: use unambiguous types in xdl_hash_record()
     @@ Metadata
       ## Commit message ##
          xdiff: use unambiguous types in xdl_hash_record()
      
     +    Convert the function signature and body to use unambiguous types. char
     +    is changed to uint8_t because this function processes bytes in memory.
     +    unsigned long to uint64_t so that the hash output is consistent across
     +    platforms. `flags` was changed from long to uint64_t to ensure the
     +    high order bits are not dropped on platforms that treat long as 32
     +    bits.
     +
          Signed-off-by: Ezekiel Newren <[email-masked]>
      
       ## xdiff-interface.c ##
  5:  a3e706ecda =  6:  59054ea0cb xdiff: split xrecord_t.ha into line_hash and minimal_perfect_hash
  6:  5767ba4ee8 =  7:  f91be17858 xdiff: make xdfile_t.nrec a size_t instead of long
  7:  4caa6a4669 !  8:  e2a6a23cc4 xdiff: make xdfile_t.nreff a size_t instead of long
     @@ xdiff/xtypes.h: typedef struct s_xdfile {
       	long *rindex;
      -	long nreff;
      +	size_t nreff;
     - 	ssize_t dstart, dend;
     + 	ptrdiff_t dstart, dend;
       } xdfile_t;
       
  8:  6dca5e6222 !  9:  3b6054945f xdiff: change rindex from long to size_t in xdfile_t
     @@ Commit message
          xdiff: change rindex from long to size_t in xdfile_t
      
          rindex describes a index offset which means it's an index into memory
     -    which should use size_t. dstart and dend will be deleted in a future
     -    patch series. Move them to the end to help avoid refactor conflicts.
     +    which should use size_t.
     +
     +    Changing the type of rindex from long to size_t has no cascading
     +    refactor impact because it is only ever used to directly index other
     +    arrays.
      
          Signed-off-by: Ezekiel Newren <[email-masked]>
      
     @@ xdiff/xtypes.h: typedef struct s_xdfile {
      -	long *rindex;
      +	size_t *rindex;
       	size_t nreff;
     - 	ssize_t dstart, dend;
     + 	ptrdiff_t dstart, dend;
       } xdfile_t;
  9:  518e5f5557 ! 10:  1856a29026 xdiff: rename rindex -> reference_index
     @@ xdiff/xtypes.h: typedef struct s_xdfile {
      -	size_t *rindex;
      +	size_t *reference_index;
       	size_t nreff;
     - 	ssize_t dstart, dend;
     + 	ptrdiff_t dstart, dend;
       } xdfile_t;

-- 
gitgitgadget