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
661db4f4
Commit
661db4f4
authored
Mar 23, 2016
by
Carlos Martín Nieto
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3704 from ethomson/tree-reuse
tree: drop the now-unnecessary entries vector
parents
0a7ce499
e2e4bae9
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
125 additions
and
46 deletions
+125
-46
src/array.h
+40
-0
src/tree.c
+29
-44
src/tree.h
+1
-2
tests/core/array.c
+55
-0
No files found.
src/array.h
View file @
661db4f4
...
@@ -82,4 +82,44 @@ on_oom:
...
@@ -82,4 +82,44 @@ on_oom:
#define git_array_valid_index(a, i) ((i) < (a).size)
#define git_array_valid_index(a, i) ((i) < (a).size)
#define git_array_foreach(a, i, element) \
for ((i) = 0; (i) < (a).size && ((element) = &(a).ptr[(i)]); (i)++)
GIT_INLINE
(
int
)
git_array__search
(
size_t
*
out
,
void
*
array_ptr
,
size_t
item_size
,
size_t
array_len
,
int
(
*
compare
)(
const
void
*
,
const
void
*
),
const
void
*
key
)
{
size_t
lim
;
unsigned
char
*
part
,
*
array
=
array_ptr
,
*
base
=
array_ptr
;
int
cmp
;
for
(
lim
=
array_len
;
lim
!=
0
;
lim
>>=
1
)
{
part
=
base
+
(
lim
>>
1
)
*
item_size
;
cmp
=
(
*
compare
)(
key
,
part
);
if
(
cmp
==
0
)
{
base
=
part
;
break
;
}
if
(
cmp
>
0
)
{
/* key > p; take right partition */
base
=
part
+
1
*
item_size
;
lim
--
;
}
/* else take left partition */
}
if
(
out
)
*
out
=
(
base
-
array
)
/
item_size
;
return
(
cmp
==
0
)
?
0
:
GIT_ENOTFOUND
;
}
#define git_array_search(out, a, cmp, key) \
git_array__search(out, (a).ptr, sizeof(*(a).ptr), (a).size, \
(cmp), (key))
#endif
#endif
src/tree.c
View file @
661db4f4
...
@@ -163,7 +163,10 @@ static int homing_search_cmp(const void *key, const void *array_member)
...
@@ -163,7 +163,10 @@ static int homing_search_cmp(const void *key, const void *array_member)
* around the area for our target file.
* around the area for our target file.
*/
*/
static
int
tree_key_search
(
static
int
tree_key_search
(
size_t
*
at_pos
,
git_vector
*
entries
,
const
char
*
filename
,
size_t
filename_len
)
size_t
*
at_pos
,
const
git_tree
*
tree
,
const
char
*
filename
,
size_t
filename_len
)
{
{
struct
tree_key_search
ksearch
;
struct
tree_key_search
ksearch
;
const
git_tree_entry
*
entry
;
const
git_tree_entry
*
entry
;
...
@@ -176,13 +179,15 @@ static int tree_key_search(
...
@@ -176,13 +179,15 @@ static int tree_key_search(
/* Initial homing search; find an entry on the tree with
/* Initial homing search; find an entry on the tree with
* the same prefix as the filename we're looking for */
* the same prefix as the filename we're looking for */
if
(
git_vector_bsearch2
(
&
homing
,
entries
,
&
homing_search_cmp
,
&
ksearch
)
<
0
)
if
(
git_array_search
(
&
homing
,
tree
->
entries
,
&
homing_search_cmp
,
&
ksearch
)
<
0
)
return
GIT_ENOTFOUND
;
/* just a signal error; not passed back to user */
return
GIT_ENOTFOUND
;
/* just a signal error; not passed back to user */
/* We found a common prefix. Look forward as long as
/* We found a common prefix. Look forward as long as
* there are entries that share the common prefix */
* there are entries that share the common prefix */
for
(
i
=
homing
;
i
<
entries
->
length
;
++
i
)
{
for
(
i
=
homing
;
i
<
tree
->
entries
.
size
;
++
i
)
{
entry
=
entries
->
contents
[
i
]
;
entry
=
git_array_get
(
tree
->
entries
,
i
)
;
if
(
homing_search_cmp
(
&
ksearch
,
entry
)
<
0
)
if
(
homing_search_cmp
(
&
ksearch
,
entry
)
<
0
)
break
;
break
;
...
@@ -202,7 +207,7 @@ static int tree_key_search(
...
@@ -202,7 +207,7 @@ static int tree_key_search(
i
=
homing
-
1
;
i
=
homing
-
1
;
do
{
do
{
entry
=
entries
->
contents
[
i
]
;
entry
=
git_array_get
(
tree
->
entries
,
i
)
;
if
(
homing_search_cmp
(
&
ksearch
,
entry
)
>
0
)
if
(
homing_search_cmp
(
&
ksearch
,
entry
)
>
0
)
break
;
break
;
...
@@ -250,8 +255,7 @@ void git_tree__free(void *_tree)
...
@@ -250,8 +255,7 @@ void git_tree__free(void *_tree)
git_tree
*
tree
=
_tree
;
git_tree
*
tree
=
_tree
;
git_odb_object_free
(
tree
->
odb_obj
);
git_odb_object_free
(
tree
->
odb_obj
);
git_vector_free
(
&
tree
->
entries
);
git_array_clear
(
tree
->
entries
);
git_array_clear
(
tree
->
entries_arr
);
git__free
(
tree
);
git__free
(
tree
);
}
}
...
@@ -303,13 +307,10 @@ static const git_tree_entry *entry_fromname(
...
@@ -303,13 +307,10 @@ static const git_tree_entry *entry_fromname(
{
{
size_t
idx
;
size_t
idx
;
/* be safe when we cast away constness - i.e. don't trigger a sort */
if
(
tree_key_search
(
&
idx
,
tree
,
name
,
name_len
)
<
0
)
assert
(
git_vector_is_sorted
(
&
tree
->
entries
));
if
(
tree_key_search
(
&
idx
,
(
git_vector
*
)
&
tree
->
entries
,
name
,
name_len
)
<
0
)
return
NULL
;
return
NULL
;
return
git_
vector_get
(
&
tree
->
entries
,
idx
);
return
git_
array_get
(
tree
->
entries
,
idx
);
}
}
const
git_tree_entry
*
git_tree_entry_byname
(
const
git_tree_entry
*
git_tree_entry_byname
(
...
@@ -324,7 +325,7 @@ const git_tree_entry *git_tree_entry_byindex(
...
@@ -324,7 +325,7 @@ const git_tree_entry *git_tree_entry_byindex(
const
git_tree
*
tree
,
size_t
idx
)
const
git_tree
*
tree
,
size_t
idx
)
{
{
assert
(
tree
);
assert
(
tree
);
return
git_
vector_get
(
&
tree
->
entries
,
idx
);
return
git_
array_get
(
tree
->
entries
,
idx
);
}
}
const
git_tree_entry
*
git_tree_entry_byid
(
const
git_tree_entry
*
git_tree_entry_byid
(
...
@@ -335,7 +336,7 @@ const git_tree_entry *git_tree_entry_byid(
...
@@ -335,7 +336,7 @@ const git_tree_entry *git_tree_entry_byid(
assert
(
tree
);
assert
(
tree
);
git_
vector_foreach
(
&
tree
->
entries
,
i
,
e
)
{
git_
array_foreach
(
tree
->
entries
,
i
,
e
)
{
if
(
memcmp
(
&
e
->
oid
->
id
,
&
id
->
id
,
sizeof
(
id
->
id
))
==
0
)
if
(
memcmp
(
&
e
->
oid
->
id
,
&
id
->
id
,
sizeof
(
id
->
id
))
==
0
)
return
e
;
return
e
;
}
}
...
@@ -345,7 +346,6 @@ const git_tree_entry *git_tree_entry_byid(
...
@@ -345,7 +346,6 @@ const git_tree_entry *git_tree_entry_byid(
int
git_tree__prefix_position
(
const
git_tree
*
tree
,
const
char
*
path
)
int
git_tree__prefix_position
(
const
git_tree
*
tree
,
const
char
*
path
)
{
{
const
git_vector
*
entries
=
&
tree
->
entries
;
struct
tree_key_search
ksearch
;
struct
tree_key_search
ksearch
;
size_t
at_pos
,
path_len
;
size_t
at_pos
,
path_len
;
...
@@ -358,21 +358,20 @@ int git_tree__prefix_position(const git_tree *tree, const char *path)
...
@@ -358,21 +358,20 @@ int git_tree__prefix_position(const git_tree *tree, const char *path)
ksearch
.
filename
=
path
;
ksearch
.
filename
=
path
;
ksearch
.
filename_len
=
(
uint16_t
)
path_len
;
ksearch
.
filename_len
=
(
uint16_t
)
path_len
;
/* be safe when we cast away constness - i.e. don't trigger a sort */
assert
(
git_vector_is_sorted
(
&
tree
->
entries
));
/* Find tree entry with appropriate prefix */
/* Find tree entry with appropriate prefix */
git_
vector_bsearch2
(
git_
array_search
(
&
at_pos
,
(
git_vector
*
)
entries
,
&
homing_search_cmp
,
&
ksearch
);
&
at_pos
,
tree
->
entries
,
&
homing_search_cmp
,
&
ksearch
);
for
(;
at_pos
<
entries
->
length
;
++
at_pos
)
{
for
(;
at_pos
<
tree
->
entries
.
size
;
++
at_pos
)
{
const
git_tree_entry
*
entry
=
entries
->
contents
[
at_pos
]
;
const
git_tree_entry
*
entry
=
git_array_get
(
tree
->
entries
,
at_pos
)
;
if
(
homing_search_cmp
(
&
ksearch
,
entry
)
<
0
)
if
(
homing_search_cmp
(
&
ksearch
,
entry
)
<
0
)
break
;
break
;
}
}
for
(;
at_pos
>
0
;
--
at_pos
)
{
for
(;
at_pos
>
0
;
--
at_pos
)
{
const
git_tree_entry
*
entry
=
entries
->
contents
[
at_pos
-
1
];
const
git_tree_entry
*
entry
=
git_array_get
(
tree
->
entries
,
at_pos
-
1
);
if
(
homing_search_cmp
(
&
ksearch
,
entry
)
>
0
)
if
(
homing_search_cmp
(
&
ksearch
,
entry
)
>
0
)
break
;
break
;
}
}
...
@@ -383,7 +382,7 @@ int git_tree__prefix_position(const git_tree *tree, const char *path)
...
@@ -383,7 +382,7 @@ int git_tree__prefix_position(const git_tree *tree, const char *path)
size_t
git_tree_entrycount
(
const
git_tree
*
tree
)
size_t
git_tree_entrycount
(
const
git_tree
*
tree
)
{
{
assert
(
tree
);
assert
(
tree
);
return
tree
->
entries
.
length
;
return
tree
->
entries
.
size
;
}
}
unsigned
int
git_treebuilder_entrycount
(
git_treebuilder
*
bld
)
unsigned
int
git_treebuilder_entrycount
(
git_treebuilder
*
bld
)
...
@@ -423,7 +422,6 @@ static int parse_mode(unsigned int *modep, const char *buffer, const char **buff
...
@@ -423,7 +422,6 @@ static int parse_mode(unsigned int *modep, const char *buffer, const char **buff
int
git_tree__parse
(
void
*
_tree
,
git_odb_object
*
odb_obj
)
int
git_tree__parse
(
void
*
_tree
,
git_odb_object
*
odb_obj
)
{
{
size_t
i
;
git_tree
*
tree
=
_tree
;
git_tree
*
tree
=
_tree
;
const
char
*
buffer
;
const
char
*
buffer
;
const
char
*
buffer_end
;
const
char
*
buffer_end
;
...
@@ -434,8 +432,8 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
...
@@ -434,8 +432,8 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
buffer
=
git_odb_object_data
(
tree
->
odb_obj
);
buffer
=
git_odb_object_data
(
tree
->
odb_obj
);
buffer_end
=
buffer
+
git_odb_object_size
(
tree
->
odb_obj
);
buffer_end
=
buffer
+
git_odb_object_size
(
tree
->
odb_obj
);
git_array_init_to_size
(
tree
->
entries
_arr
,
DEFAULT_TREE_SIZE
);
git_array_init_to_size
(
tree
->
entries
,
DEFAULT_TREE_SIZE
);
GITERR_CHECK_ARRAY
(
tree
->
entries
_arr
);
GITERR_CHECK_ARRAY
(
tree
->
entries
);
while
(
buffer
<
buffer_end
)
{
while
(
buffer
<
buffer_end
)
{
git_tree_entry
*
entry
;
git_tree_entry
*
entry
;
...
@@ -450,9 +448,9 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
...
@@ -450,9 +448,9 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
return
tree_error
(
"Failed to parse tree. Object is corrupted"
,
NULL
);
return
tree_error
(
"Failed to parse tree. Object is corrupted"
,
NULL
);
filename_len
=
nul
-
buffer
;
filename_len
=
nul
-
buffer
;
/*
* Allocate the entry and store it in the entries vector
*/
/*
Allocate the entry
*/
{
{
entry
=
git_array_alloc
(
tree
->
entries
_arr
);
entry
=
git_array_alloc
(
tree
->
entries
);
GITERR_CHECK_ALLOC
(
entry
);
GITERR_CHECK_ALLOC
(
entry
);
entry
->
attr
=
attr
;
entry
->
attr
=
attr
;
...
@@ -465,18 +463,6 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
...
@@ -465,18 +463,6 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
buffer
+=
GIT_OID_RAWSZ
;
buffer
+=
GIT_OID_RAWSZ
;
}
}
/* Add the entries to the vector here, as we may reallocate during the loop */
if
(
git_vector_init
(
&
tree
->
entries
,
tree
->
entries_arr
.
size
,
entry_sort_cmp
)
<
0
)
return
-
1
;
for
(
i
=
0
;
i
<
tree
->
entries_arr
.
size
;
i
++
)
{
if
(
git_vector_insert
(
&
tree
->
entries
,
git_array_get
(
tree
->
entries_arr
,
i
))
<
0
)
return
-
1
;
}
/* The tree is sorted by definition. Bad inputs give bad outputs */
tree
->
entries
.
flags
|=
GIT_VECTOR_SORTED
;
return
0
;
return
0
;
}
}
...
@@ -700,7 +686,7 @@ int git_treebuilder_new(
...
@@ -700,7 +686,7 @@ int git_treebuilder_new(
if
(
source
!=
NULL
)
{
if
(
source
!=
NULL
)
{
git_tree_entry
*
entry_src
;
git_tree_entry
*
entry_src
;
git_
vector_foreach
(
&
source
->
entries
,
i
,
entry_src
)
{
git_
array_foreach
(
source
->
entries
,
i
,
entry_src
)
{
if
(
append_entry
(
if
(
append_entry
(
bld
,
entry_src
->
filename
,
bld
,
entry_src
->
filename
,
entry_src
->
oid
,
entry_src
->
oid
,
...
@@ -845,7 +831,6 @@ int git_treebuilder_write(git_oid *oid, git_treebuilder *bld)
...
@@ -845,7 +831,6 @@ int git_treebuilder_write(git_oid *oid, git_treebuilder *bld)
error
=
-
1
;
error
=
-
1
;
}
}
git_vector_free
(
&
entries
);
if
(
!
error
&&
if
(
!
error
&&
!
(
error
=
git_repository_odb__weakptr
(
&
odb
,
bld
->
repo
)))
!
(
error
=
git_repository_odb__weakptr
(
&
odb
,
bld
->
repo
)))
...
@@ -975,7 +960,7 @@ static int tree_walk(
...
@@ -975,7 +960,7 @@ static int tree_walk(
size_t
i
;
size_t
i
;
const
git_tree_entry
*
entry
;
const
git_tree_entry
*
entry
;
git_
vector_foreach
(
&
tree
->
entries
,
i
,
entry
)
{
git_
array_foreach
(
tree
->
entries
,
i
,
entry
)
{
if
(
preorder
)
{
if
(
preorder
)
{
error
=
callback
(
path
->
ptr
,
entry
,
payload
);
error
=
callback
(
path
->
ptr
,
entry
,
payload
);
if
(
error
<
0
)
{
/* negative value stops iteration */
if
(
error
<
0
)
{
/* negative value stops iteration */
...
...
src/tree.h
View file @
661db4f4
...
@@ -24,8 +24,7 @@ struct git_tree_entry {
...
@@ -24,8 +24,7 @@ struct git_tree_entry {
struct
git_tree
{
struct
git_tree
{
git_object
object
;
git_object
object
;
git_odb_object
*
odb_obj
;
git_odb_object
*
odb_obj
;
git_array_t
(
git_tree_entry
)
entries_arr
;
git_array_t
(
git_tree_entry
)
entries
;
git_vector
entries
;
};
};
struct
git_treebuilder
{
struct
git_treebuilder
{
...
...
tests/core/array.c
0 → 100644
View file @
661db4f4
#include "clar_libgit2.h"
#include "array.h"
static
int
int_lookup
(
const
void
*
k
,
const
void
*
a
)
{
const
int
*
one
=
(
const
int
*
)
k
;
int
*
two
=
(
int
*
)
a
;
return
*
one
-
*
two
;
}
#define expect_pos(k, n, ret) \
key = (k); \
cl_assert_equal_i((ret), \
git_array_search(&p, integers, int_lookup, &key)); \
cl_assert_equal_i((n), p);
void
test_core_array__bsearch2
(
void
)
{
git_array_t
(
int
)
integers
=
GIT_ARRAY_INIT
;
int
*
i
,
key
;
size_t
p
;
i
=
git_array_alloc
(
integers
);
*
i
=
2
;
i
=
git_array_alloc
(
integers
);
*
i
=
3
;
i
=
git_array_alloc
(
integers
);
*
i
=
5
;
i
=
git_array_alloc
(
integers
);
*
i
=
7
;
i
=
git_array_alloc
(
integers
);
*
i
=
7
;
i
=
git_array_alloc
(
integers
);
*
i
=
8
;
i
=
git_array_alloc
(
integers
);
*
i
=
13
;
i
=
git_array_alloc
(
integers
);
*
i
=
21
;
i
=
git_array_alloc
(
integers
);
*
i
=
25
;
i
=
git_array_alloc
(
integers
);
*
i
=
42
;
i
=
git_array_alloc
(
integers
);
*
i
=
69
;
i
=
git_array_alloc
(
integers
);
*
i
=
121
;
i
=
git_array_alloc
(
integers
);
*
i
=
256
;
i
=
git_array_alloc
(
integers
);
*
i
=
512
;
i
=
git_array_alloc
(
integers
);
*
i
=
513
;
i
=
git_array_alloc
(
integers
);
*
i
=
514
;
i
=
git_array_alloc
(
integers
);
*
i
=
516
;
i
=
git_array_alloc
(
integers
);
*
i
=
516
;
i
=
git_array_alloc
(
integers
);
*
i
=
517
;
/* value to search for, expected position, return code */
expect_pos
(
3
,
1
,
GIT_OK
);
expect_pos
(
2
,
0
,
GIT_OK
);
expect_pos
(
1
,
0
,
GIT_ENOTFOUND
);
expect_pos
(
25
,
8
,
GIT_OK
);
expect_pos
(
26
,
9
,
GIT_ENOTFOUND
);
expect_pos
(
42
,
9
,
GIT_OK
);
expect_pos
(
50
,
10
,
GIT_ENOTFOUND
);
expect_pos
(
68
,
10
,
GIT_ENOTFOUND
);
expect_pos
(
256
,
12
,
GIT_OK
);
}
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