Skip to content

Commit 668ba59

Browse files
authored
Merge pull request #996 from carlosmn/cmn/count-tree-limit
tree: allow for a tree limit in `Tree::count_recursive`
2 parents 29312a4 + 445f307 commit 668ba59

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

ext/rugged/rugged_tree.c

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,32 +83,41 @@ static VALUE rb_git_tree_entrycount(VALUE self)
8383

8484
struct rugged_treecount_cb_payload
8585
{
86-
int count;
87-
int limit;
86+
int entry_count;
87+
int tree_count;
88+
int entry_limit;
89+
int tree_limit;
8890
};
8991

9092
static int rugged__treecount_cb(const char *root, const git_tree_entry *entry, void *data)
9193
{
9294
struct rugged_treecount_cb_payload *payload = data;
9395

94-
if (payload->limit >= 0 && payload->count >= payload->limit) {
96+
if (payload->entry_limit >= 0 && payload->entry_count >= payload->entry_limit) {
97+
return -1;
98+
} else if (payload->tree_limit >= 0 && payload->tree_count >= payload->tree_limit) {
9599
return -1;
96100
} else if(git_tree_entry_type(entry) == GIT_OBJ_TREE) {
101+
++(payload->tree_count);
97102
return 0;
98103
} else {
99-
++(payload->count);
104+
++(payload->entry_count);
100105
return 1;
101106
}
102107
}
103108

104109
/*
105110
* call-seq:
106-
* tree.count_recursive(limit=nil) -> count
111+
* tree.count_recursive(entry_limit=nil, tree_limit=nil) -> count
107112
*
108-
* `limit` - The maximum number of blobs to the count in the repository.
109-
* Rugged will stop walking the tree after `limit` items to avoid long
113+
* `entry_limit` - The maximum number of blobs to the count in the repository.
114+
* Rugged will stop walking the trees after `entry_limit` items to avoid long
110115
* execution times.
111116
*
117+
* `tree_limit` - The maximum number of trees to look in. Rugged will stop
118+
* walking the trees after `tree_limit` items to avoid long execution times. If
119+
* it is unset but `entry_limit` is set, `tree_limit` is set to the same value.
120+
*
112121
* Return the number of blobs (up to the limit) contained in the tree and
113122
* all subtrees.
114123
*/
@@ -117,18 +126,29 @@ static VALUE rb_git_tree_entrycount_recursive(int argc, VALUE* argv, VALUE self)
117126
git_tree *tree;
118127
int error;
119128
struct rugged_treecount_cb_payload payload;
120-
VALUE rb_limit;
129+
VALUE rb_entry_limit, rb_tree_limit;
121130

122131
TypedData_Get_Struct(self, git_tree, &rugged_object_type, tree);
123132

124-
rb_scan_args(argc, argv, "01", &rb_limit);
133+
rb_scan_args(argc, argv, "02", &rb_entry_limit, &rb_tree_limit);
134+
135+
payload.entry_limit = -1;
136+
payload.tree_limit = -1;
137+
payload.entry_count = 0;
138+
payload.tree_count = 0;
125139

126-
payload.limit = -1;
127-
payload.count = 0;
140+
if (!NIL_P(rb_entry_limit)) {
141+
Check_Type(rb_entry_limit, T_FIXNUM);
142+
payload.entry_limit = FIX2INT(rb_entry_limit);
143+
}
144+
145+
if (!NIL_P(rb_tree_limit)) {
146+
Check_Type(rb_tree_limit, T_FIXNUM);
147+
payload.tree_limit = FIX2INT(rb_tree_limit);
148+
}
128149

129-
if (!NIL_P(rb_limit)) {
130-
Check_Type(rb_limit, T_FIXNUM);
131-
payload.limit = FIX2INT(rb_limit);
150+
if (payload.tree_limit < 0 && payload.entry_limit >= 0) {
151+
payload.tree_limit = payload.entry_limit;
132152
}
133153

134154

@@ -141,7 +161,7 @@ static VALUE rb_git_tree_entrycount_recursive(int argc, VALUE* argv, VALUE self)
141161

142162
rugged_exception_check(error);
143163

144-
return INT2FIX(payload.count);
164+
return INT2FIX(payload.entry_count);
145165
}
146166

147167
/*

test/tree_test.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ def test_read_tree_data
4848
assert_equal 6, @tree.count_recursive
4949
assert_equal 5, @tree.count_recursive(5)
5050
assert_equal 6, @tree.count_recursive(10)
51+
assert_equal 2, @tree.count_recursive(10, 1)
52+
assert_equal 4, @tree.count_recursive(10, 2)
5153
assert_raises(TypeError) do
5254
@tree.count_recursive("NaN")
5355
end

0 commit comments

Comments
 (0)