Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ccan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mirror
ccan
Commits
d01dfe4e
Commit
d01dfe4e
authored
Aug 30, 2010
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tdb2: more common code
Use hash_add() when resizing hash, too.
parent
2c56e4d9
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
49 additions
and
58 deletions
+49
-58
ccan/tdb2/tdb.c
ccan/tdb2/tdb.c
+49
-58
No files found.
ccan/tdb2/tdb.c
View file @
d01dfe4e
...
...
@@ -549,12 +549,38 @@ static int update_rec_hdr(struct tdb_context *tdb,
return
tdb_write_convert
(
tdb
,
off
,
rec
,
sizeof
(
*
rec
));
}
static
int
hash_add
(
struct
tdb_context
*
tdb
,
uint64_t
hash
,
tdb_off_t
off
)
{
tdb_off_t
i
,
hoff
,
len
,
num
;
/* Look for next space. */
i
=
(
hash
&
((
1ULL
<<
tdb
->
header
.
v
.
hash_bits
)
-
1
));
len
=
(
1ULL
<<
tdb
->
header
.
v
.
hash_bits
)
-
i
;
num
=
tdb_find_zero_off
(
tdb
,
hash_off
(
tdb
,
i
),
len
);
if
(
unlikely
(
num
==
len
))
{
/* We wrapped. Look through start of hash table. */
hoff
=
hash_off
(
tdb
,
0
);
len
=
(
1ULL
<<
tdb
->
header
.
v
.
hash_bits
);
num
=
tdb_find_zero_off
(
tdb
,
hoff
,
len
);
if
(
i
==
len
)
{
tdb
->
ecode
=
TDB_ERR_CORRUPT
;
tdb
->
log
(
tdb
,
TDB_DEBUG_FATAL
,
tdb
->
log_priv
,
"hash_add: full hash table!
\n
"
);
return
-
1
;
}
}
/* FIXME: Encode extra hash bits! */
return
tdb_write_off
(
tdb
,
hash_off
(
tdb
,
i
+
num
),
off
);
}
/* If we fail, others will try after us. */
static
void
enlarge_hash
(
struct
tdb_context
*
tdb
)
{
tdb_off_t
newoff
,
oldoff
,
i
;
tdb_len_t
hlen
;
uint64_t
h
,
num
=
1ULL
<<
tdb
->
header
.
v
.
hash_bits
;
uint64_t
num
=
1ULL
<<
tdb
->
header
.
v
.
hash_bits
;
struct
tdb_used_record
pad
,
*
r
;
/* FIXME: We should do this without holding locks throughout. */
...
...
@@ -565,6 +591,7 @@ static void enlarge_hash(struct tdb_context *tdb)
if
((
1ULL
<<
tdb
->
header
.
v
.
hash_bits
)
!=
num
)
goto
unlock
;
again:
/* Allocate our new array. */
hlen
=
num
*
sizeof
(
tdb_off_t
)
*
2
;
newoff
=
alloc
(
tdb
,
0
,
hlen
,
0
,
false
);
...
...
@@ -573,9 +600,7 @@ static void enlarge_hash(struct tdb_context *tdb)
if
(
unlikely
(
newoff
==
0
))
{
if
(
tdb_expand
(
tdb
,
0
,
hlen
,
false
)
==
-
1
)
goto
unlock
;
newoff
=
alloc
(
tdb
,
0
,
hlen
,
0
,
false
);
if
(
newoff
==
TDB_OFF_ERR
||
newoff
==
0
)
goto
unlock
;
goto
again
;
}
/* Step over record header! */
newoff
+=
sizeof
(
struct
tdb_used_record
);
...
...
@@ -584,49 +609,40 @@ static void enlarge_hash(struct tdb_context *tdb)
if
(
zero_out
(
tdb
,
newoff
,
hlen
)
==
-
1
)
goto
unlock
;
/* Update header now so we can use normal routines. */
oldoff
=
tdb
->
header
.
v
.
hash_off
;
tdb
->
header
.
v
.
hash_bits
++
;
tdb
->
header
.
v
.
hash_off
=
newoff
;
/* FIXME: If the space before is empty, we know this is in its ideal
* location. Or steal a bit from the pointer to avoid rehash. */
for
(
i
=
tdb_find_nonzero_off
(
tdb
,
hash_off
(
tdb
,
0
),
num
);
i
<
num
;
i
+=
tdb_find_nonzero_off
(
tdb
,
hash_off
(
tdb
,
i
),
num
-
i
))
{
for
(
i
=
0
;
i
<
num
;
i
++
)
{
tdb_off_t
off
;
off
=
tdb_read_off
(
tdb
,
hash_off
(
tdb
,
i
));
off
=
tdb_read_off
(
tdb
,
oldoff
+
i
*
sizeof
(
tdb_off_t
));
if
(
unlikely
(
off
==
TDB_OFF_ERR
))
goto
unlock
;
if
(
unlikely
(
!
off
))
{
tdb
->
ecode
=
TDB_ERR_CORRUPT
;
tdb
->
log
(
tdb
,
TDB_DEBUG_FATAL
,
tdb
->
log_priv
,
"enlarge_hash: zero hash bucket!
\n
"
);
goto
unlock
;
}
/* Find next empty hash slot. */
for
(
h
=
hash_record
(
tdb
,
off
);
tdb_read_off
(
tdb
,
newoff
+
(
h
&
((
num
*
2
)
-
1
))
*
sizeof
(
tdb_off_t
))
!=
0
;
h
++
);
/* FIXME: Encode extra hash bits! */
if
(
tdb_write_off
(
tdb
,
newoff
+
(
h
&
((
num
*
2
)
-
1
))
*
sizeof
(
tdb_off_t
),
off
)
==
-
1
)
goto
unlock
;
i
++
;
goto
oldheader
;
if
(
off
&&
hash_add
(
tdb
,
hash_record
(
tdb
,
off
),
off
)
==
-
1
)
goto
oldheader
;
}
/* Free up old hash. */
oldoff
=
tdb
->
header
.
v
.
hash_off
-
sizeof
(
*
r
);
r
=
tdb_get
(
tdb
,
oldoff
,
&
pad
,
sizeof
(
*
r
));
r
=
tdb_get
(
tdb
,
oldoff
-
sizeof
(
*
r
),
&
pad
,
sizeof
(
*
r
));
if
(
!
r
)
goto
unlock
;
add_free_record
(
tdb
,
oldoff
,
goto
oldheader
;
add_free_record
(
tdb
,
oldoff
-
sizeof
(
*
r
)
,
sizeof
(
*
r
)
+
rec_data_length
(
r
)
+
rec_extra_padding
(
r
));
/* Now we write the modified header. */
tdb
->
header
.
v
.
hash_bits
++
;
tdb
->
header
.
v
.
hash_off
=
newoff
;
write_header
(
tdb
);
unlock:
tdb_allrecord_unlock
(
tdb
,
F_WRLCK
);
return
;
oldheader:
tdb
->
header
.
v
.
hash_bits
--
;
tdb
->
header
.
v
.
hash_off
=
oldoff
;
goto
unlock
;
}
/* This is the core routine which searches the hashtable for an entry.
...
...
@@ -797,31 +813,6 @@ struct tdb_data tdb_fetch(struct tdb_context *tdb, struct tdb_data key)
return
ret
;
}
static
int
hash_add
(
struct
tdb_context
*
tdb
,
uint64_t
h
,
tdb_off_t
off
)
{
tdb_off_t
i
,
hoff
,
len
,
num
;
/* Look for next space. */
i
=
(
h
&
((
1ULL
<<
tdb
->
header
.
v
.
hash_bits
)
-
1
));
len
=
(
1ULL
<<
tdb
->
header
.
v
.
hash_bits
)
-
i
;
num
=
tdb_find_zero_off
(
tdb
,
hash_off
(
tdb
,
i
),
len
);
if
(
unlikely
(
num
==
len
))
{
/* We wrapped. Look through start of hash table. */
hoff
=
hash_off
(
tdb
,
0
);
len
=
(
1ULL
<<
tdb
->
header
.
v
.
hash_bits
);
num
=
tdb_find_zero_off
(
tdb
,
hoff
,
len
);
if
(
i
==
len
)
{
tdb
->
ecode
=
TDB_ERR_CORRUPT
;
tdb
->
log
(
tdb
,
TDB_DEBUG_FATAL
,
tdb
->
log_priv
,
"hash_add: full hash table!
\n
"
);
return
-
1
;
}
}
/* FIXME: Encode extra hash bits! */
return
tdb_write_off
(
tdb
,
hash_off
(
tdb
,
i
+
num
),
off
);
}
int
tdb_delete
(
struct
tdb_context
*
tdb
,
struct
tdb_data
key
)
{
tdb_off_t
i
,
bucket
,
off
,
start
,
num
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment