Return the same index and odb objects in successive calls
Instead of creating a new Go object each time Repository.Index()/Odb() are called, return the same one as long as the underlying pointer remains the same.
This commit is contained in:
parent
66e1c47619
commit
57ceb04c78
|
@ -22,6 +22,20 @@ func TestCreateRepoAndStage(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestIndexTwoCalls(t *testing.T) {
|
||||
repo := createTestRepo(t)
|
||||
defer os.RemoveAll(repo.Workdir())
|
||||
|
||||
idx1, err := repo.Index()
|
||||
checkFatal(t, err)
|
||||
idx2, err := repo.Index()
|
||||
checkFatal(t, err)
|
||||
|
||||
if idx1 != idx2 {
|
||||
t.Fatal("Two Index() calls give different objects")
|
||||
}
|
||||
}
|
||||
|
||||
func checkFatal(t *testing.T, err error) {
|
||||
if err == nil {
|
||||
return
|
||||
|
|
6
odb.go
6
odb.go
|
@ -17,6 +17,12 @@ type Odb struct {
|
|||
ptr *C.git_odb
|
||||
}
|
||||
|
||||
func newOdbFromC(ptr *C.git_odb) *Odb {
|
||||
odb := &Odb{ptr}
|
||||
runtime.SetFinalizer(odb, (*Odb).Free)
|
||||
return odb
|
||||
}
|
||||
|
||||
func (v *Odb) Exists(oid *Oid) bool {
|
||||
ret := C.git_odb_exists(v.ptr, oid.toC())
|
||||
return ret != 0
|
||||
|
|
14
odb_test.go
14
odb_test.go
|
@ -33,3 +33,17 @@ func TestOdbStream(t *testing.T) {
|
|||
t.Fatal("Wrong data written")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOdbTwoCalls(t *testing.T) {
|
||||
repo := createTestRepo(t)
|
||||
defer os.RemoveAll(repo.Workdir())
|
||||
|
||||
odb1, err := repo.Odb()
|
||||
checkFatal(t, err)
|
||||
odb2, err := repo.Odb()
|
||||
checkFatal(t, err)
|
||||
|
||||
if odb1 != odb2 {
|
||||
t.Fatal("Two Odb() calls return different objects")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,11 @@ import (
|
|||
// Repository
|
||||
type Repository struct {
|
||||
ptr *C.git_repository
|
||||
|
||||
// These are kept so that two repo.Index() or repo.Odb() calls
|
||||
// return the same object, as we do in the library
|
||||
idx *Index
|
||||
odb *Odb
|
||||
}
|
||||
|
||||
func OpenRepository(path string) (*Repository, error) {
|
||||
|
@ -72,17 +77,22 @@ func (v *Repository) Config() (*Config, error) {
|
|||
}
|
||||
|
||||
func (v *Repository) Index() (*Index, error) {
|
||||
var ptr *C.git_index
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
var ptr *C.git_index
|
||||
ret := C.git_repository_index(&ptr, v.ptr)
|
||||
if ret < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
return newIndexFromC(ptr), nil
|
||||
if v.idx != nil && v.idx.ptr == ptr {
|
||||
C.git_index_free(ptr) // decrease the refcount
|
||||
return v.idx, nil
|
||||
}
|
||||
|
||||
v.idx = newIndexFromC(ptr)
|
||||
return v.idx, nil
|
||||
}
|
||||
|
||||
func (v *Repository) lookupType(oid *Oid, t ObjectType) (Object, error) {
|
||||
|
@ -246,18 +256,23 @@ func (v *Odb) Free() {
|
|||
C.git_odb_free(v.ptr)
|
||||
}
|
||||
|
||||
func (v *Repository) Odb() (odb *Odb, err error) {
|
||||
odb = new(Odb)
|
||||
|
||||
func (v *Repository) Odb() (*Odb, error) {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
if ret := C.git_repository_odb(&odb.ptr, v.ptr); ret < 0 {
|
||||
var ptr *C.git_odb
|
||||
if ret := C.git_repository_odb(&ptr, v.ptr); ret < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
runtime.SetFinalizer(odb, (*Odb).Free)
|
||||
return
|
||||
if v.odb != nil && v.odb.ptr == ptr {
|
||||
C.git_odb_free(ptr) // decrease the refcount
|
||||
return v.odb, nil
|
||||
}
|
||||
|
||||
|
||||
v.odb = newOdbFromC(ptr)
|
||||
return v.odb, nil
|
||||
}
|
||||
|
||||
func (repo *Repository) Path() string {
|
||||
|
|
|
@ -153,7 +153,7 @@ func (sub *Submodule) Save() error {
|
|||
func (sub *Submodule) Owner() *Repository {
|
||||
repo := C.git_submodule_owner(sub.ptr)
|
||||
//FIXME: how to handle dangling references ?
|
||||
return &Repository{repo}
|
||||
return &Repository{ptr: repo}
|
||||
}
|
||||
|
||||
func (sub *Submodule) Name() string {
|
||||
|
|
Loading…
Reference in New Issue