Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
525d961c
Commit
525d961c
authored
Dec 20, 2012
by
Carlos Martín Nieto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pack: refcount entries and add a mutex around cache access
parent
c0f4a011
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
35 additions
and
10 deletions
+35
-10
src/pack.c
+33
-9
src/pack.h
+2
-1
No files found.
src/pack.c
View file @
525d961c
...
@@ -47,13 +47,13 @@ static int packfile_error(const char *message)
...
@@ -47,13 +47,13 @@ static int packfile_error(const char *message)
}
}
static
git_pack_cache_entry
*
new_cache_object
(
git_
off_t
off
,
git_
rawobj
*
source
)
static
git_pack_cache_entry
*
new_cache_object
(
git_rawobj
*
source
)
{
{
git_pack_cache_entry
*
e
=
git__malloc
(
sizeof
(
git_pack_cache_entry
));
git_pack_cache_entry
*
e
=
git__malloc
(
sizeof
(
git_pack_cache_entry
));
if
(
!
e
)
if
(
!
e
)
return
NULL
;
return
NULL
;
e
->
off
=
off
;
e
->
refcount
.
val
=
0
;
memcpy
(
&
e
->
raw
,
source
,
sizeof
(
git_rawobj
));
memcpy
(
&
e
->
raw
,
source
,
sizeof
(
git_rawobj
));
return
e
;
return
e
;
...
@@ -63,6 +63,7 @@ static void free_cache_object(void *o)
...
@@ -63,6 +63,7 @@ static void free_cache_object(void *o)
{
{
git_pack_cache_entry
*
e
=
(
git_pack_cache_entry
*
)
o
;
git_pack_cache_entry
*
e
=
(
git_pack_cache_entry
*
)
o
;
assert
(
e
->
refcount
.
val
==
0
);
if
(
e
!=
NULL
)
{
if
(
e
!=
NULL
)
{
git__free
(
e
->
raw
.
data
);
git__free
(
e
->
raw
.
data
);
git__free
(
e
);
git__free
(
e
);
...
@@ -361,7 +362,7 @@ static int packfile_unpack_delta(
...
@@ -361,7 +362,7 @@ static int packfile_unpack_delta(
{
{
git_off_t
base_offset
,
base_key
;
git_off_t
base_offset
,
base_key
;
git_rawobj
base
,
delta
;
git_rawobj
base
,
delta
;
git_pack_cache_entry
*
cached
;
git_pack_cache_entry
*
cached
=
NULL
;
int
error
,
found_base
=
0
;
int
error
,
found_base
=
0
;
khiter_t
k
;
khiter_t
k
;
...
@@ -375,15 +376,21 @@ static int packfile_unpack_delta(
...
@@ -375,15 +376,21 @@ static int packfile_unpack_delta(
if
(
!
p
->
bases
)
{
if
(
!
p
->
bases
)
{
p
->
bases
=
git_offmap_alloc
();
p
->
bases
=
git_offmap_alloc
();
GITERR_CHECK_ALLOC
(
p
->
bases
);
GITERR_CHECK_ALLOC
(
p
->
bases
);
git_mutex_init
(
&
p
->
bases_lock
);
}
}
base_key
=
base_offset
;
/* git_packfile_unpack modifies base_offset */
base_key
=
base_offset
;
/* git_packfile_unpack modifies base_offset */
git_mutex_lock
(
&
p
->
bases_lock
);
k
=
kh_get
(
off
,
p
->
bases
,
base_offset
);
k
=
kh_get
(
off
,
p
->
bases
,
base_offset
);
if
(
k
!=
kh_end
(
p
->
bases
))
{
/* found it */
if
(
k
!=
kh_end
(
p
->
bases
))
{
/* found it */
cached
=
kh_value
(
p
->
bases
,
k
);
cached
=
kh_value
(
p
->
bases
,
k
);
git_atomic_inc
(
&
cached
->
refcount
);
found_base
=
1
;
found_base
=
1
;
memcpy
(
&
base
,
&
cached
->
raw
,
sizeof
(
git_rawobj
));
memcpy
(
&
base
,
&
cached
->
raw
,
sizeof
(
git_rawobj
));
}
else
{
/* have to inflate it */
}
git_mutex_unlock
(
&
p
->
bases_lock
);
if
(
!
cached
)
{
/* have to inflate it */
error
=
git_packfile_unpack
(
&
base
,
p
,
&
base_offset
);
error
=
git_packfile_unpack
(
&
base
,
p
,
&
base_offset
);
/*
/*
...
@@ -410,12 +417,27 @@ static int packfile_unpack_delta(
...
@@ -410,12 +417,27 @@ static int packfile_unpack_delta(
if
(
error
<
0
)
if
(
error
<
0
)
goto
on_error
;
goto
on_error
;
if
(
!
found_base
)
{
if
(
found_base
)
{
cached
=
new_cache_object
(
base_key
,
&
base
);
git_atomic_dec
(
&
cached
->
refcount
);
}
else
{
cached
=
new_cache_object
(
&
base
);
if
(
cached
)
{
if
(
cached
)
{
k
=
kh_put
(
off
,
p
->
bases
,
base_key
,
&
error
);
int
exists
;
assert
(
error
!=
0
);
kh_value
(
p
->
bases
,
k
)
=
cached
;
git_mutex_lock
(
&
p
->
bases_lock
);
/* Add it to the cache if nobody else has */
exists
=
kh_exist
(
p
->
bases
,
kh_get
(
off
,
p
->
bases
,
base_key
));
if
(
!
exists
)
{
k
=
kh_put
(
off
,
p
->
bases
,
base_key
,
&
error
);
assert
(
error
!=
0
);
kh_value
(
p
->
bases
,
k
)
=
cached
;
}
git_mutex_unlock
(
&
p
->
bases_lock
);
/* Somebody beat us to adding it into the cache */
if
(
exists
)
{
free_cache_object
(
cached
);
git__free
(
base
.
data
);
}
}
}
}
}
...
@@ -738,6 +760,8 @@ static int packfile_open(struct git_pack_file *p)
...
@@ -738,6 +760,8 @@ static int packfile_open(struct git_pack_file *p)
p
->
bases
=
git_offmap_alloc
();
p
->
bases
=
git_offmap_alloc
();
GITERR_CHECK_ALLOC
(
p
->
bases
);
GITERR_CHECK_ALLOC
(
p
->
bases
);
git_mutex_init
(
&
p
->
bases_lock
);
/* TODO: open with noatime */
/* TODO: open with noatime */
p
->
mwf
.
fd
=
git_futils_open_ro
(
p
->
pack_name
);
p
->
mwf
.
fd
=
git_futils_open_ro
(
p
->
pack_name
);
...
...
src/pack.h
View file @
525d961c
...
@@ -54,7 +54,7 @@ struct git_pack_idx_header {
...
@@ -54,7 +54,7 @@ struct git_pack_idx_header {
};
};
typedef
struct
git_pack_cache_entry
{
typedef
struct
git_pack_cache_entry
{
git_
off_t
off
;
git_
atomic
refcount
;
git_rawobj
raw
;
git_rawobj
raw
;
}
git_pack_cache_entry
;
}
git_pack_cache_entry
;
...
@@ -77,6 +77,7 @@ struct git_pack_file {
...
@@ -77,6 +77,7 @@ struct git_pack_file {
git_vector
cache
;
git_vector
cache
;
git_oid
**
oids
;
git_oid
**
oids
;
git_mutex
bases_lock
;
git_offmap
*
bases
;
/* delta base cache */
git_offmap
*
bases
;
/* delta base cache */
/* something like ".git/objects/pack/xxxxx.pack" */
/* something like ".git/objects/pack/xxxxx.pack" */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment