/src/samba/lib/util/idtree_random.c
Line | Count | Source |
1 | | /* |
2 | | Unix SMB/CIFS implementation. |
3 | | |
4 | | very efficient functions to manage mapping a id (such as a fnum) to |
5 | | a pointer. This is used for fnum and search id allocation. |
6 | | |
7 | | Copyright (C) Andrew Tridgell 2004 |
8 | | |
9 | | This code is derived from lib/idr.c in the 2.6 Linux kernel, which was |
10 | | written by Jim Houston jim.houston@ccur.com, and is |
11 | | Copyright (C) 2002 by Concurrent Computer Corporation |
12 | | |
13 | | This program is free software; you can redistribute it and/or modify |
14 | | it under the terms of the GNU General Public License as published by |
15 | | the Free Software Foundation; either version 2 of the License, or |
16 | | (at your option) any later version. |
17 | | |
18 | | This program is distributed in the hope that it will be useful, |
19 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 | | GNU General Public License for more details. |
22 | | |
23 | | You should have received a copy of the GNU General Public License |
24 | | along with this program. If not, see <http://www.gnu.org/licenses/>. |
25 | | */ |
26 | | |
27 | | /* |
28 | | see the section marked "public interface" below for documentation |
29 | | */ |
30 | | |
31 | | /** |
32 | | * @file |
33 | | */ |
34 | | |
35 | | #include "replace.h" |
36 | | #include "samba_util.h" /* generate_random() */ |
37 | | #include "idtree.h" |
38 | | #include "idtree_random.h" |
39 | | |
40 | | /** |
41 | | allocate a new id randomly in the given range |
42 | | */ |
43 | | _PUBLIC_ int idr_get_new_random(struct idr_context *idp, |
44 | | void *ptr, |
45 | | int starting_id, |
46 | | int limit) |
47 | 0 | { |
48 | 0 | int id; |
49 | | |
50 | | /* first try a random starting point in the whole range, and if that fails, |
51 | | then start randomly in the bottom half of the range. This can only |
52 | | fail if the range is over half full, and finally fallback to any |
53 | | free id */ |
54 | 0 | id = idr_get_new_above( |
55 | 0 | idp, ptr, starting_id+(generate_random() % limit), limit); |
56 | 0 | if (id == -1) { |
57 | 0 | id = idr_get_new_above( |
58 | 0 | idp, |
59 | 0 | ptr, |
60 | 0 | starting_id+(generate_random()%(limit/2)), |
61 | 0 | limit); |
62 | 0 | } |
63 | 0 | if (id == -1) { |
64 | 0 | id = idr_get_new_above(idp, ptr, starting_id, limit); |
65 | 0 | } |
66 | |
|
67 | 0 | return id; |
68 | 0 | } |