Move git_off_t to git_object_size_t - #5123
Conversation
88fc191 to
f22e3fc
Compare
|
Aha, we do actually treat |
5d18fc5 to
33ff267
Compare
a2a587d to
b871167
Compare
|
Rebased to fix conflicts. |
4f033a1 to
54c9fb4
Compare
|
Rebased. |
|
@pks-t any thoughts here? I'd love to think about a release 🔜 and include this. |
|
On Fri, Aug 16, 2019 at 02:41:53AM -0700, Edward Thomson wrote:
@pks-t any thoughts here? I'd love to think about a release 🔜
and include this.
I hope to be able to find enought time to pick up some loose ends
in libgit2 this Friday. And I fully agree that we should start
thinking about a release soon, it's been quite some time.
|
pks-t
left a comment
There was a problem hiding this comment.
This looks mostly good to me. There's two APIs where I'm sceptical about using git_object_size_t with the diff API and the futils interfaces, though
| int num_lines; /**< Number of newline characters in content */ | ||
| size_t content_len; /**< Number of bytes of data */ | ||
| git_off_t content_offset; /**< Offset in the original file to the content */ | ||
| git_object_size_t content_offset; /**< Offset in the original file to the content */ |
There was a problem hiding this comment.
Does it really make sense to use git_object_size_t here? Diffs aren't necessary referring to any objects at all but, so it seems a bit dirty to me to mix these up.
There was a problem hiding this comment.
Hmm, perhaps not. The rare good use of git_off_t?
| fc->opts_flags = opts ? opts->flags : GIT_DIFF_NORMAL; | ||
|
|
||
| if (opts && opts->max_size >= 0) | ||
| if (opts && (int64_t)opts->max_size >= 0) |
There was a problem hiding this comment.
Mh. This comparison doesn't make sense anymore, as max_size is now unsigned. If it becomes negative due to casting then I'd consider this a bug.
There was a problem hiding this comment.
Yeah, ignore my last comment. You're right.
| * Defaults to 512MB. | ||
| */ | ||
| git_off_t max_size; | ||
| git_object_size_t max_size; |
There was a problem hiding this comment.
Hm, this changes our API, doesn't it?
There was a problem hiding this comment.
In practice, if callers ever provided a negative value, it was caught in diff_file_content_init_common, and ignored.
#5123 (diff) was doing the same. So as-is we are API compatible, but if we remove that odd-looking check, then we are in fact changing the API.
There was a problem hiding this comment.
Moved this back to a signed int for sanity.
| line.content_offset = bufs[1].ptr - info->xd_old_data.ptr; | ||
| else | ||
| line.content_offset = -1; | ||
| line.content_offset = GIT_OBJECT_SIZE_MAX; |
There was a problem hiding this comment.
This changes semantics too, as we pass these to the callers
There was a problem hiding this comment.
Sorry, can you give me more information about what you mean?
There was a problem hiding this comment.
We're populating the git_diff_line struct here, which we directly pass to the user via the data_cb callback. So previously callers would've seen content_offset = -1, now he sees content_offset = UINT64_MAX if a line was unchanged. I could imagine people having checks for that
There was a problem hiding this comment.
Moved this back to a signed int to support this.
| } | ||
|
|
||
| git_off_t git_futils_filesize(git_file fd) | ||
| int git_futils_filesize(git_object_size_t *out, git_file fd) |
There was a problem hiding this comment.
Not sure how I feel about these. off_t directly maps to the mmap functions of the OS, using git_object_size_t feels weird to me
There was a problem hiding this comment.
Well, mmap does take an off_t but only for the offset into the file. That doesn't correspond to the length of the file or memory-mapped segment.
I definitely don't think that we should use a signed type for file length, it simply can't be negative. We wouldn't want to use size_t here, since on a 32-bit system, we want to be able to get the size of a file larger than 4 GB.
We could call this the more direct uint64_t here.
There was a problem hiding this comment.
Hum. Some platforms handle negative offsets in mmap just fine and treat it as valid. It's questionable though whether we're going to ever need that, especially considering that we'd have to fight with cross-platform behaviour here. So 👍 for uint64_t.
c689857 to
284d1d9
Compare
| typedef struct { | ||
| struct timespec mtime; | ||
| git_off_t size; | ||
| git_object_size_t size; |
There was a problem hiding this comment.
Some file APIs now use uint64_t, some use git_object_size_t. Shouldn't this one here use uint64_t, as well?
There was a problem hiding this comment.
Yes, this probably makes sense.
|
|
||
|
|
||
| int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset) | ||
| int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset) |
There was a problem hiding this comment.
Quick question, no need to change: why did you opt to convert to off64_t instead of just typedeffing git_off_t to off64_t?
There was a problem hiding this comment.
I thought that it was clearer for internal uses to use something Very Obviously 64 bit, and something that is a Standard Type. git_off_t feels like the sort of thing that is perhaps useful for our external API, but less useful for our internal.
Your comment did make me rethink a few things, so I actually kept git_off_t in the external type places that it was used. I think this is a pretty reasonable compromise.
| } | ||
|
|
||
| assert(sizeof(git_off_t) == 8); | ||
| assert(sizeof(off64_t) == 8); |
There was a problem hiding this comment.
Does this make sense? I mean it's very unlikely that off64_t is ever going to be something else than 8 bytes
There was a problem hiding this comment.
😬 Yes, that's very true. Removed entirely.
Introduce `git_object_size_t`, an unsigned type that we can use for the maximum size of git objects.
Instead of using a signed type (`off_t`) use a new `git_object_size_t` for the sizes of objects.
Instead of using a signed type (`off_t`) use a new `git_object_size_t` for the sizes of objects.
Instead of using a signed type (`off_t`) use `uint64_t` for the maximum size of files.
Instead of using a signed type (`off_t`) use a new `git_object_size_t` for the sizes of objects.
Instead of using a signed type (`off_t`) use an unsigned `uint64_t` for the size of the files.
994e41e to
6c13cf6
Compare
64 bit types are always 64 bit.
Prefer `off64_t` to `git_off_t` for internal visibility.
Prefer `off64_t` to `git_off_t` internally for visibility.
Use int64_t internally for type visibility.
Prefer `off64_t` internally.
f48d720 to
6460e8a
Compare
| if (!fc->file->size) | ||
| error = git_futils_filesize(&fc->file->size, fd); | ||
|
|
||
| if (error < 0 || !fc->file->size) |
There was a problem hiding this comment.
This does look a bit weird. Seems like we do not allow loading empty files from disk here. Your change only makes code a lot clearer here, so I'm fine with this as is.
git_off_tis problematic: first, it's used to represent the size ofa blob, but that's represented in git as an
unsigned long, meaningthat we've lost a bit (on 64-bit machines). Second,
git_off_tis apoor name, suggesting that it's an offset, not a size (which makes
sense, given that it's a signed type).
Migrate
git_off_ttogit_object_size_t, an unsigned 64-bit type.