2 * This file is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2,
4 * as published by the Free Software Foundation.
6 * In addition to the permissions in the GNU General Public License,
7 * the authors give you unlimited permission to link the compiled
8 * version of this file into combinations with other programs,
9 * and to distribute those combinations without any restriction
10 * coming from the use of this file. (The General Public License
11 * restrictions do apply in other respects; for example, they cover
12 * modification of the file, and distribution when not linked into
13 * a combined executable.)
15 * This file is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; see the file COPYING. If not, write to
22 * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
27 #include "revobject.h"
29 const float max_load_factor
= 0.65;
31 unsigned int git_revpool_table__hash(const git_oid
*id
)
33 const unsigned int m
= 0x5bd1e995;
36 unsigned int h
= 0xA8A3D5;
39 for (i
= 0; i
< GIT_OID_RAWSZ
/ 4; ++i
)
41 unsigned int k
= ((unsigned int *)id
->id
)[i
];
57 git_revpool_table
*git_revpool_table_create(unsigned int min_size
)
59 git_revpool_table
*table
;
62 table
= git__malloc(sizeof(table
));
67 // round up size to closest power of 2
69 min_size
|= min_size
>> 1;
70 min_size
|= min_size
>> 2;
71 min_size
|= min_size
>> 4;
72 min_size
|= min_size
>> 8;
73 min_size
|= min_size
>> 16;
75 table
->size_mask
= min_size
;
77 table
->max_count
= (min_size
+ 1) * max_load_factor
;
79 table
->nodes
= git__malloc((min_size
+ 1) * sizeof(git_revpool_node
*));
81 if (table
->nodes
== NULL
)
87 for (i
= 0; i
<= min_size
; ++i
)
88 table
->nodes
[i
] = NULL
;
93 int git_revpool_table_insert(git_revpool_table
*table
, git_revpool_object
*object
)
95 git_revpool_node
*node
;
96 unsigned int index
, hash
;
101 if (table
->count
+ 1 > table
->max_count
)
102 git_revpool_table_resize(table
);
104 node
= git__malloc(sizeof(git_revpool_node
));
108 hash
= git_revpool_table__hash(&object
->id
);
109 index
= (hash
& table
->size_mask
);
111 node
->object
= object
;
113 node
->next
= table
->nodes
[index
];
115 table
->nodes
[index
] = node
;
121 git_revpool_object
*git_revpool_table_lookup(git_revpool_table
*table
, const git_oid
*id
)
123 git_revpool_node
*node
;
124 unsigned int index
, hash
;
129 hash
= git_revpool_table__hash(id
);
130 index
= (hash
& table
->size_mask
);
131 node
= table
->nodes
[index
];
135 if (node
->hash
== hash
&& git_oid_cmp(id
, &node
->object
->id
) == 0)
144 void git_revpool_table_resize(git_revpool_table
*table
)
146 git_revpool_node
**new_nodes
;
147 unsigned int new_size
, i
;
149 new_size
= (table
->size_mask
+ 1) * 2;
151 new_nodes
= git__malloc(new_size
* sizeof(git_revpool_node
*));
152 if (new_nodes
== NULL
)
155 memset(new_nodes
, 0x0, new_size
* sizeof(git_revpool_node
*));
157 for (i
= 0; i
<= table
->size_mask
; ++i
)
162 while ((n
= table
->nodes
[i
]) != NULL
)
164 table
->nodes
[i
] = n
->next
;
165 index
= n
->hash
& (new_size
- 1);
166 n
->next
= new_nodes
[index
];
167 new_nodes
[index
] = n
;
172 table
->nodes
= new_nodes
;
173 table
->size_mask
= (new_size
- 1);
174 table
->max_count
= new_size
* max_load_factor
;
178 void git_revpool_table_free(git_revpool_table
*table
)