Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CP-40669: Restore database should not require ref as the first #4781

Merged
merged 1 commit into from
Aug 30, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions ocaml/database/db_xml.ml
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,24 @@ module From = struct
f acc
| (_, "table"), [((_, "name"), tblname)] ->
f (tableset, Table.empty, tblname, manifest)
| (_, "row"), ((_, "ref"), rf) :: rest ->
(* Remove any other duplicate "ref"s which might have sneaked in there *)
let rest = List.filter (fun ((_, k), _) -> k <> "ref") rest in
| (_, "row"), rest ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Altogether, this code is traversing lists multiple times and is inefficient if these lists are long. But that problem is already pre-existing.

The problem at hand is to find the first "ref" entry and to ignore the others. The solution is to split the list based on the key and we expect to find at least one entry. I think the code achieving this could be kept closer together - a sketch is below:

let ref, rest =
  match List.partition (fun ((_, k) -> k = "ref")) rest with
  | r::_, rest -> r,rest
  | [] -> raise ...

let ref_l, rest =
List.partition (fun ((_, k), _) -> k = "ref") rest
in

let ctime_l, rest =
List.partition (fun ((_, k), _) -> k = "__ctime") rest
in
let mtime_l, rest =
List.partition (fun ((_, k), _) -> k = "__mtime") rest
in
let rf =
match ref_l with
| (_, ref) :: _ ->
ref (* Pick up the first ref and ignore others *)
| [] ->
raise (Unmarshall_error "Row does not have ref atrribute")
in
let ctime =
match ctime_l with
| [(_, ctime_s)] ->
Expand Down