Skip to content

handles, merge, odb: changes for Go 1.6 pointer passing rules#282

Merged
carlosmn merged 5 commits intolibgit2:masterfrom
ianlancetaylor:master
Feb 18, 2016
Merged

handles, merge, odb: changes for Go 1.6 pointer passing rules#282
carlosmn merged 5 commits intolibgit2:masterfrom
ianlancetaylor:master

Conversation

@ianlancetaylor
Copy link
Copy Markdown
Contributor

Comment thread merge.go Outdated
if input.Contents != nil {
c.ptr = (*C.char)(unsafe.Pointer(&input.Contents[0]))
toFree = C.CString(string(input.Contents))
c.ptr = toFree
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes us allocate an extra buffer. We also don't actually know that what we have is a string. It's some buffer, so making it go through the string type seems wrong.

If there's no way to work around this in Go, I'd rather we write some C so we're passing &input.Contents[0] to a C function so the rules make it OK for us to re-use this buffer.

@carlosmn
Copy link
Copy Markdown
Member

There's a bunch of unrelated whitespace change that makes this harder to read, could you drop that?

@ianlancetaylor
Copy link
Copy Markdown
Contributor Author

Pull request updated.

I dropped the whitespace changes, but they were entirely from gofmt. I would suggest running gofmt on the Go files.

@carlosmn
Copy link
Copy Markdown
Member

The next branch did get a go fmt treatment, but I've kept master as-is to reduce the amount of in-flight work that would conflict due to whitespace change.

Thanks!

carlosmn added a commit that referenced this pull request Feb 18, 2016
handles, merge, odb: changes for Go 1.6 pointer passing rules
@carlosmn carlosmn merged commit f05417a into libgit2:master Feb 18, 2016
navytux added a commit to navytux/git-backup that referenced this pull request May 25, 2018
Currently for every file -> blob, and blob -> file we invoke git
subprocess (cat-file or hash-object). We also invoke git subprocess for
every tag read/write and the same for commits and this 1-subprocess per
1 object has very high overhead.

The ways to avoid such overhead could be:

1) for every kind of operation spawn git service process, like e.g.
   `git cat-file --batch` for reading files, and only do request/reply
   per object with it.

2) use some go library to work with git repository ourselves.

"1" can work but:

    - at present there is no counterpart of `cat-file --batch` for
      e.g. `hash-object` - i.e. we cannot write objects without quirks
      or patching git.

    - even if we add support for hashing via request/reply, as all
      requests are processed sequentially on git side by e.g. `git
      cat-file --batch`, we won't be able to leverage parallelism.

    - request/reply has also latency attached.

For "2" we have roughly the following choices:

    - use cgo bindings to libgit2   (git2go)

    - use some pure-go git library

Pure-go approach has pros that it by design avoids problems related to
tricky CGo pointer C <-> Go passing rules. The fact that this was sorted
out by go team itself only during 1.6 cycle

    golang/go#12416

tells a lot. The net is full of examples where those were hard to get,
and git2go in particular has a story of e.g. heap corruption (the bug
was on golang itself side and fixed only for 1.5)

    libgit2/git2go#223
    https://groups.google.com/forum/#!topic/golang-nuts/Vi1HD-54BTA/discussion

However there is no good (to my knowledge) pure-go git library, and the
family of forks around github.com/speedata/gogit either:

    - works 3x slower compared to git2go

      ( or the same 3x in serial mode compared to e.g. `git cat-file --batch`
        as in serial mode git subservice and git2go has roughly similar performance )

    - or does not work at all (e.g. barfing out on REF_DELTA pack
      entries, etc)

So because of 3x slowdown, pure-go way is currently a no-runner.

Since one person from golang team cared to update git2go to properly
follow the CGo rules

    libgit2/git2go#282

we can be relatively confident about git2go bindings quality and try to
use it.

This commit only hooks git2go into the build, subcommands and to Sha1
for to/from Oid conversion. We'll be switching places to git2go
incrementally in upcoming patches.

NOTE for now we need git2go from next branch for

    libgit2/git2go@cf7553e7

The plan is to eventually switch to

    gopkg.in/libgit2/git2go.v25

once it is out.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants