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
c8f79c2b
Commit
c8f79c2b
authored
Dec 21, 2012
by
Carlos Martín Nieto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pack: abstract out the cache into its own functions
parent
525d961c
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
91 additions
and
53 deletions
+91
-53
src/pack.c
+80
-51
src/pack.h
+11
-2
No files found.
src/pack.c
View file @
c8f79c2b
...
@@ -46,14 +46,16 @@ static int packfile_error(const char *message)
...
@@ -46,14 +46,16 @@ static int packfile_error(const char *message)
return
-
1
;
return
-
1
;
}
}
/********************
* Delta base cache
********************/
static
git_pack_cache_entry
*
new_cache_object
(
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__
calloc
(
1
,
sizeof
(
git_pack_cache_entry
));
if
(
!
e
)
if
(
!
e
)
return
NULL
;
return
NULL
;
e
->
refcount
.
val
=
0
;
memcpy
(
&
e
->
raw
,
source
,
sizeof
(
git_rawobj
));
memcpy
(
&
e
->
raw
,
source
,
sizeof
(
git_rawobj
));
return
e
;
return
e
;
...
@@ -70,6 +72,75 @@ static void free_cache_object(void *o)
...
@@ -70,6 +72,75 @@ static void free_cache_object(void *o)
}
}
}
}
static
void
cache_free
(
git_pack_cache
*
cache
)
{
khiter_t
k
;
if
(
cache
->
entries
)
{
for
(
k
=
kh_begin
(
cache
->
entries
);
k
!=
kh_end
(
cache
->
entries
);
k
++
)
{
if
(
kh_exist
(
cache
->
entries
,
k
))
free_cache_object
(
kh_value
(
cache
->
entries
,
k
));
}
git_offmap_free
(
cache
->
entries
);
}
}
static
int
cache_init
(
git_pack_cache
*
cache
)
{
memset
(
cache
,
0
,
sizeof
(
git_pack_cache
));
cache
->
entries
=
git_offmap_alloc
();
GITERR_CHECK_ALLOC
(
cache
->
entries
);
cache
->
memory_limit
=
GIT_PACK_CACHE_MEMORY_LIMIT
;
git_mutex_init
(
&
cache
->
lock
);
return
0
;
}
static
git_pack_cache_entry
*
cache_get
(
git_pack_cache
*
cache
,
size_t
offset
)
{
khiter_t
k
;
git_pack_cache_entry
*
entry
=
NULL
;
git_mutex_lock
(
&
cache
->
lock
);
k
=
kh_get
(
off
,
cache
->
entries
,
offset
);
if
(
k
!=
kh_end
(
cache
->
entries
))
{
/* found it */
entry
=
kh_value
(
cache
->
entries
,
k
);
git_atomic_inc
(
&
entry
->
refcount
);
entry
->
uses
++
;
}
git_mutex_unlock
(
&
cache
->
lock
);
return
entry
;
}
static
int
cache_add
(
git_pack_cache
*
cache
,
git_rawobj
*
base
,
git_off_t
offset
)
{
git_pack_cache_entry
*
entry
;
int
error
,
exists
=
0
;
khiter_t
k
;
entry
=
new_cache_object
(
base
);
if
(
entry
)
{
git_mutex_lock
(
&
cache
->
lock
);
/* Add it to the cache if nobody else has */
exists
=
kh_get
(
off
,
cache
->
entries
,
offset
)
!=
kh_end
(
cache
->
entries
);
if
(
!
exists
)
{
k
=
kh_put
(
off
,
cache
->
entries
,
offset
,
&
error
);
assert
(
error
!=
0
);
kh_value
(
cache
->
entries
,
k
)
=
entry
;
}
git_mutex_unlock
(
&
cache
->
lock
);
/* Somebody beat us to adding it into the cache */
if
(
exists
)
{
git__free
(
entry
);
return
-
1
;
}
}
return
0
;
}
/***********************************************************
/***********************************************************
*
*
* PACK INDEX METHODS
* PACK INDEX METHODS
...
@@ -364,7 +435,6 @@ static int packfile_unpack_delta(
...
@@ -364,7 +435,6 @@ static int packfile_unpack_delta(
git_rawobj
base
,
delta
;
git_rawobj
base
,
delta
;
git_pack_cache_entry
*
cached
=
NULL
;
git_pack_cache_entry
*
cached
=
NULL
;
int
error
,
found_base
=
0
;
int
error
,
found_base
=
0
;
khiter_t
k
;
base_offset
=
get_delta_base
(
p
,
w_curs
,
curpos
,
delta_type
,
obj_offset
);
base_offset
=
get_delta_base
(
p
,
w_curs
,
curpos
,
delta_type
,
obj_offset
);
git_mwindow_close
(
w_curs
);
git_mwindow_close
(
w_curs
);
...
@@ -373,22 +443,14 @@ static int packfile_unpack_delta(
...
@@ -373,22 +443,14 @@ static int packfile_unpack_delta(
if
(
base_offset
<
0
)
/* must actually be an error code */
if
(
base_offset
<
0
)
/* must actually be an error code */
return
(
int
)
base_offset
;
return
(
int
)
base_offset
;
if
(
!
p
->
bases
)
{
if
(
!
p
->
bases
.
entries
&&
(
cache_init
(
&
p
->
bases
)
<
0
))
p
->
bases
=
git_offmap_alloc
();
return
-
1
;
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
);
if
((
cached
=
cache_get
(
&
p
->
bases
,
base_offset
))
!=
NULL
)
{
k
=
kh_get
(
off
,
p
->
bases
,
base_offset
);
if
(
k
!=
kh_end
(
p
->
bases
))
{
/* found it */
cached
=
kh_value
(
p
->
bases
,
k
);
git_atomic_inc
(
&
cached
->
refcount
);
found_base
=
1
;
memcpy
(
&
base
,
&
cached
->
raw
,
sizeof
(
git_rawobj
));
memcpy
(
&
base
,
&
cached
->
raw
,
sizeof
(
git_rawobj
));
found_base
=
1
;
}
}
git_mutex_unlock
(
&
p
->
bases_lock
);
if
(
!
cached
)
{
/* have to inflate it */
if
(
!
cached
)
{
/* have to inflate it */
error
=
git_packfile_unpack
(
&
base
,
p
,
&
base_offset
);
error
=
git_packfile_unpack
(
&
base
,
p
,
&
base_offset
);
...
@@ -417,29 +479,10 @@ static int packfile_unpack_delta(
...
@@ -417,29 +479,10 @@ static int packfile_unpack_delta(
if
(
error
<
0
)
if
(
error
<
0
)
goto
on_error
;
goto
on_error
;
if
(
found_base
)
{
if
(
found_base
)
git_atomic_dec
(
&
cached
->
refcount
);
git_atomic_dec
(
&
cached
->
refcount
);
}
else
{
else
if
(
cache_add
(
&
p
->
bases
,
&
base
,
base_key
)
<
0
)
cached
=
new_cache_object
(
&
base
);
if
(
cached
)
{
int
exists
;
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
);
git__free
(
base
.
data
);
}
}
}
on_error:
on_error:
git__free
(
delta
.
data
);
git__free
(
delta
.
data
);
...
@@ -721,18 +764,9 @@ static struct git_pack_file *packfile_alloc(size_t extra)
...
@@ -721,18 +764,9 @@ static struct git_pack_file *packfile_alloc(size_t extra)
void
packfile_free
(
struct
git_pack_file
*
p
)
void
packfile_free
(
struct
git_pack_file
*
p
)
{
{
khiter_t
k
;
assert
(
p
);
assert
(
p
);
if
(
p
->
bases
)
{
cache_free
(
&
p
->
bases
);
for
(
k
=
kh_begin
(
p
->
bases
);
k
!=
kh_end
(
p
->
bases
);
k
++
)
{
if
(
kh_exist
(
p
->
bases
,
k
))
free_cache_object
(
kh_value
(
p
->
bases
,
k
));
}
git_offmap_free
(
p
->
bases
);
}
git_mwindow_free_all
(
&
p
->
mwf
);
git_mwindow_free_all
(
&
p
->
mwf
);
git_mwindow_file_deregister
(
&
p
->
mwf
);
git_mwindow_file_deregister
(
&
p
->
mwf
);
...
@@ -758,11 +792,6 @@ static int packfile_open(struct git_pack_file *p)
...
@@ -758,11 +792,6 @@ static int packfile_open(struct git_pack_file *p)
if
(
!
p
->
index_map
.
data
&&
pack_index_open
(
p
)
<
0
)
if
(
!
p
->
index_map
.
data
&&
pack_index_open
(
p
)
<
0
)
return
git_odb__error_notfound
(
"failed to open packfile"
,
NULL
);
return
git_odb__error_notfound
(
"failed to open packfile"
,
NULL
);
p
->
bases
=
git_offmap_alloc
();
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
);
if
(
p
->
mwf
.
fd
<
0
)
{
if
(
p
->
mwf
.
fd
<
0
)
{
...
...
src/pack.h
View file @
c8f79c2b
...
@@ -54,6 +54,7 @@ struct git_pack_idx_header {
...
@@ -54,6 +54,7 @@ struct git_pack_idx_header {
};
};
typedef
struct
git_pack_cache_entry
{
typedef
struct
git_pack_cache_entry
{
int
uses
;
/* enough? */
git_atomic
refcount
;
git_atomic
refcount
;
git_rawobj
raw
;
git_rawobj
raw
;
}
git_pack_cache_entry
;
}
git_pack_cache_entry
;
...
@@ -62,6 +63,15 @@ typedef struct git_pack_cache_entry {
...
@@ -62,6 +63,15 @@ typedef struct git_pack_cache_entry {
GIT__USE_OFFMAP
;
GIT__USE_OFFMAP
;
#define GIT_PACK_CACHE_MEMORY_LIMIT 2 * 1024 * 1024;
typedef
struct
{
size_t
memory_used
;
size_t
memory_limit
;
git_mutex
lock
;
git_offmap
*
entries
;
}
git_pack_cache
;
struct
git_pack_file
{
struct
git_pack_file
{
git_mwindow_file
mwf
;
git_mwindow_file
mwf
;
git_map
index_map
;
git_map
index_map
;
...
@@ -77,8 +87,7 @@ struct git_pack_file {
...
@@ -77,8 +87,7 @@ struct git_pack_file {
git_vector
cache
;
git_vector
cache
;
git_oid
**
oids
;
git_oid
**
oids
;
git_mutex
bases_lock
;
git_pack_cache
bases
;
/* delta base cache */
git_offmap
*
bases
;
/* delta base cache */
/* something like ".git/objects/pack/xxxxx.pack" */
/* something like ".git/objects/pack/xxxxx.pack" */
char
pack_name
[
GIT_FLEX_ARRAY
];
/* more */
char
pack_name
[
GIT_FLEX_ARRAY
];
/* more */
...
...
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