| 1940 | } *pbase_tree; |
| 1941 | |
| 1942 | static struct pbase_tree_cache *pbase_tree_get(const struct object_id *oid) |
| 1943 | { |
| 1944 | struct pbase_tree_cache *ent, *nent; |
| 1945 | void *data; |
| 1946 | unsigned long size; |
| 1947 | size_t size_st = 0; |
| 1948 | enum object_type type; |
| 1949 | int neigh; |
| 1950 | int my_ix = pbase_tree_cache_ix(oid); |
| 1951 | int available_ix = -1; |
| 1952 | |
| 1953 | /* pbase-tree-cache acts as a limited hashtable. |
| 1954 | * your object will be found at your index or within a few |
| 1955 | * slots after that slot if it is cached. |
| 1956 | */ |
| 1957 | for (neigh = 0; neigh < 8; neigh++) { |
| 1958 | ent = pbase_tree_cache[my_ix]; |
| 1959 | if (ent && oideq(&ent->oid, oid)) { |
| 1960 | ent->ref++; |
| 1961 | return ent; |
| 1962 | } |
| 1963 | else if (((available_ix < 0) && (!ent || !ent->ref)) || |
| 1964 | ((0 <= available_ix) && |
| 1965 | (!ent && pbase_tree_cache[available_ix]))) |
| 1966 | available_ix = my_ix; |
| 1967 | if (!ent) |
| 1968 | break; |
| 1969 | my_ix = pbase_tree_cache_ix_incr(my_ix); |
| 1970 | } |
| 1971 | |
| 1972 | /* Did not find one. Either we got a bogus request or |
| 1973 | * we need to read and perhaps cache. |
| 1974 | */ |
| 1975 | data = odb_read_object(the_repository->objects, oid, &type, &size_st); |
| 1976 | size = cast_size_t_to_ulong(size_st); |
| 1977 | if (!data) |
| 1978 | return NULL; |
| 1979 | if (type != OBJ_TREE) { |
| 1980 | free(data); |
| 1981 | return NULL; |
| 1982 | } |
| 1983 | |
| 1984 | /* We need to either cache or return a throwaway copy */ |
| 1985 | |
| 1986 | if (available_ix < 0) |
| 1987 | ent = NULL; |
| 1988 | else { |
| 1989 | ent = pbase_tree_cache[available_ix]; |
| 1990 | my_ix = available_ix; |
| 1991 | } |
| 1992 | |
| 1993 | if (!ent) { |
| 1994 | nent = xmalloc(sizeof(*nent)); |
| 1995 | nent->temporary = (available_ix < 0); |
| 1996 | } |
| 1997 | else { |
| 1998 | /* evict and reuse */ |
| 1999 | free(ent->tree_data); |
no test coverage detected