2 Trivial Database 2: traverse function.
3 Copyright (C) Rusty Russell 2010
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include <ccan/likely/likely.h>
21 int64_t tdb_traverse_(struct tdb_context
*tdb
,
22 int (*fn
)(struct tdb_context
*,
23 TDB_DATA
, TDB_DATA
, void *),
27 struct traverse_info tinfo
;
32 for (ecode
= first_in_hash(tdb
, &tinfo
, &k
, &d
.dsize
);
34 ecode
= next_in_hash(tdb
, &tinfo
, &k
, &d
.dsize
)) {
35 d
.dptr
= k
.dptr
+ k
.dsize
;
38 if (fn
&& fn(tdb
, k
, d
, p
)) {
40 tdb
->last_error
= TDB_SUCCESS
;
46 if (ecode
!= TDB_ERR_NOEXIST
) {
47 return tdb
->last_error
= ecode
;
49 tdb
->last_error
= TDB_SUCCESS
;
53 enum TDB_ERROR
tdb_firstkey(struct tdb_context
*tdb
, struct tdb_data
*key
)
55 struct traverse_info tinfo
;
57 return tdb
->last_error
= first_in_hash(tdb
, &tinfo
, key
, NULL
);
60 /* We lock twice, not very efficient. We could keep last key & tinfo cached. */
61 enum TDB_ERROR
tdb_nextkey(struct tdb_context
*tdb
, struct tdb_data
*key
)
63 struct traverse_info tinfo
;
65 struct tdb_used_record rec
;
67 tinfo
.prev
= find_and_lock(tdb
, *key
, F_RDLCK
, &h
, &rec
, &tinfo
);
69 if (TDB_OFF_IS_ERR(tinfo
.prev
)) {
70 return tdb
->last_error
= tinfo
.prev
;
72 tdb_unlock_hashes(tdb
, h
.hlock_start
, h
.hlock_range
, F_RDLCK
);
74 return tdb
->last_error
= next_in_hash(tdb
, &tinfo
, key
, NULL
);
77 static int wipe_one(struct tdb_context
*tdb
,
78 TDB_DATA key
, TDB_DATA data
, enum TDB_ERROR
*ecode
)
80 *ecode
= tdb_delete(tdb
, key
);
81 return (*ecode
!= TDB_SUCCESS
);
84 enum TDB_ERROR
tdb_wipe_all(struct tdb_context
*tdb
)
89 ecode
= tdb_allrecord_lock(tdb
, F_WRLCK
, TDB_LOCK_WAIT
, false);
90 if (ecode
!= TDB_SUCCESS
)
91 return tdb
->last_error
= ecode
;
93 /* FIXME: Be smarter. */
94 count
= tdb_traverse(tdb
, wipe_one
, &ecode
);
97 tdb_allrecord_unlock(tdb
, F_WRLCK
);
98 return tdb
->last_error
= ecode
;