Fix a cdb bug

This commit is contained in:
Neale Pickett 2010-12-08 15:54:25 -07:00
parent 11998b91ca
commit 83a76d3695
2 changed files with 44 additions and 43 deletions

51
cdb.ml
View File

@ -253,7 +253,7 @@ let open_cdb_in fn =
let close_cdb_in cdf =
close_in cdf.f
(** Get a stream of matches.
(** Get a list of matches.
@param cdf the cdb file
@param key the key to search
@ -262,39 +262,39 @@ let get_matches cdf key =
let kh = hash key in
(* Find out where the hash table is *)
let hpos, hlen = cdf.tables.(hash_to_table kh) in
let rec loop x =
if(x >= hlen) then (
None
) else (
let rec loop x acc =
if (x >= hlen) then
acc
else
let acc' =
(* Calculate the slot containing these entries *)
let lslot = ((hash_to_bucket kh hlen) + x) mod hlen in
let spos = Int32.add (Int32.of_int (lslot * 8)) hpos in
LargeFile.seek_in cdf.f (Int64.of_int32 spos);
let _ = LargeFile.seek_in cdf.f (Int64.of_int32 spos) in
let h = read_le32 cdf.f in
let pos = read_le32 cdf.f in
(* validate that we a real bucket *)
if (h = kh) && ((Int32.compare pos Int32.zero) > 0) then (
LargeFile.seek_in cdf.f (Int64.of_int32 pos);
if (h = kh) && ((Int32.compare pos Int32.zero) > 0) then
let _ = LargeFile.seek_in cdf.f (Int64.of_int32 pos) in
let klen = read_le cdf.f in
if (klen = String.length key) then (
if (klen = String.length key) then
let dlen = read_le cdf.f in
let rkey = String.create klen in
really_input cdf.f rkey 0 klen;
if(rkey = key) then (
if (rkey = key) then
let rdata = String.create dlen in
really_input cdf.f rdata 0 dlen;
Some(rdata)
) else (
loop (x + 1)
)
) else (
loop (x + 1)
)
) else (
loop (x + 1)
)
) in
Stream.from loop
rdata :: acc
else
acc
else
acc
else
acc
in
loop (x + 1) acc'
in
List.rev (loop 0 [])
(**
Find the first record with the given key.
@ -303,7 +303,8 @@ let get_matches cdf key =
@param key the key to find
*)
let find cdf key =
try
Stream.next (get_matches cdf key)
with Stream.Failure ->
match (get_matches cdf key) with
| [] ->
raise Not_found
| r :: _ ->
r

View File

@ -32,7 +32,7 @@ type cdb_file = {
val open_cdb_in : string -> cdb_file
val close_cdb_in : cdb_file -> unit
val get_matches : cdb_file -> string -> string Stream.t
val get_matches : cdb_file -> string -> string list
val find : cdb_file -> string -> string
(*