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

View File

@ -32,7 +32,7 @@ type cdb_file = {
val open_cdb_in : string -> cdb_file val open_cdb_in : string -> cdb_file
val close_cdb_in : cdb_file -> unit 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 val find : cdb_file -> string -> string
(* (*