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) {
|
func checkFatal(t *testing.T, err error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return
|
return
|
||||||
|
|
6
odb.go
6
odb.go
|
@ -17,6 +17,12 @@ type Odb struct {
|
||||||
ptr *C.git_odb
|
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 {
|
func (v *Odb) Exists(oid *Oid) bool {
|
||||||
ret := C.git_odb_exists(v.ptr, oid.toC())
|
ret := C.git_odb_exists(v.ptr, oid.toC())
|
||||||
return ret != 0
|
return ret != 0
|
||||||
|
|
16
odb_test.go
16
odb_test.go
|
@ -32,4 +32,18 @@ func TestOdbStream(t *testing.T) {
|
||||||
if stream.Id.Cmp(expectedId) != 0 {
|
if stream.Id.Cmp(expectedId) != 0 {
|
||||||
t.Fatal("Wrong data written")
|
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
|
// Repository
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
ptr *C.git_repository
|
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) {
|
func OpenRepository(path string) (*Repository, error) {
|
||||||
|
@ -72,17 +77,22 @@ func (v *Repository) Config() (*Config, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Repository) Index() (*Index, error) {
|
func (v *Repository) Index() (*Index, error) {
|
||||||
var ptr *C.git_index
|
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
var ptr *C.git_index
|
||||||
ret := C.git_repository_index(&ptr, v.ptr)
|
ret := C.git_repository_index(&ptr, v.ptr)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return nil, LastError()
|
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) {
|
func (v *Repository) lookupType(oid *Oid, t ObjectType) (Object, error) {
|
||||||
|
@ -246,18 +256,23 @@ func (v *Odb) Free() {
|
||||||
C.git_odb_free(v.ptr)
|
C.git_odb_free(v.ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Repository) Odb() (odb *Odb, err error) {
|
func (v *Repository) Odb() (*Odb, error) {
|
||||||
odb = new(Odb)
|
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
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()
|
return nil, LastError()
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.SetFinalizer(odb, (*Odb).Free)
|
if v.odb != nil && v.odb.ptr == ptr {
|
||||||
return
|
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 {
|
func (repo *Repository) Path() string {
|
||||||
|
|
|
@ -153,7 +153,7 @@ func (sub *Submodule) Save() error {
|
||||||
func (sub *Submodule) Owner() *Repository {
|
func (sub *Submodule) Owner() *Repository {
|
||||||
repo := C.git_submodule_owner(sub.ptr)
|
repo := C.git_submodule_owner(sub.ptr)
|
||||||
//FIXME: how to handle dangling references ?
|
//FIXME: how to handle dangling references ?
|
||||||
return &Repository{repo}
|
return &Repository{ptr: repo}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sub *Submodule) Name() string {
|
func (sub *Submodule) Name() string {
|
||||||
|
|
Loading…
Reference in New Issue