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

85
cdb.ml
View File

@ -127,7 +127,7 @@ let process_table cdc table_start slot_table slot_pointers i tc =
let rec find_where where = let rec find_where where =
match ht.(where) with match ht.(where) with
| None -> | None ->
where where
| _ -> | _ ->
if ((where + 1) = len) then (find_where 0) if ((where + 1) = len) then (find_where 0)
else (find_where (where + 1)) else (find_where (where + 1))
@ -253,48 +253,48 @@ 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
*) *)
let get_matches cdf key = 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
(* Calculate the slot containing these entries *) let acc' =
let lslot = ((hash_to_bucket kh hlen) + x) mod hlen in (* Calculate the slot containing these entries *)
let spos = Int32.add (Int32.of_int (lslot * 8)) hpos in let lslot = ((hash_to_bucket kh hlen) + x) mod hlen in
LargeFile.seek_in cdf.f (Int64.of_int32 spos); let spos = Int32.add (Int32.of_int (lslot * 8)) hpos in
let h = read_le32 cdf.f in let _ = LargeFile.seek_in cdf.f (Int64.of_int32 spos) in
let pos = read_le32 cdf.f in let h = read_le32 cdf.f in
(* validate that we a real bucket *) let pos = read_le32 cdf.f in
if (h = kh) && ((Int32.compare pos Int32.zero) > 0) then ( (* validate that we a real bucket *)
LargeFile.seek_in cdf.f (Int64.of_int32 pos); if (h = kh) && ((Int32.compare pos Int32.zero) > 0) then
let klen = read_le cdf.f in let _ = LargeFile.seek_in cdf.f (Int64.of_int32 pos) in
if (klen = String.length key) then ( let klen = read_le cdf.f in
let dlen = read_le cdf.f in if (klen = String.length key) then
let rkey = String.create klen in let dlen = read_le cdf.f in
really_input cdf.f rkey 0 klen; let rkey = String.create klen in
if(rkey = key) then ( really_input cdf.f rkey 0 klen;
let rdata = String.create dlen in if (rkey = key) then
really_input cdf.f rdata 0 dlen; let rdata = String.create dlen in
Some(rdata) really_input cdf.f rdata 0 dlen;
) else ( rdata :: acc
loop (x + 1) else
) acc
) else ( else
loop (x + 1) acc
) else
) else ( acc
loop (x + 1) in
) loop (x + 1) acc'
) in in
Stream.from loop List.rev (loop 0 [])
(** (**
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
(* (*