[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v1 5/6] tools/ocaml/xenstored: use more efficient node trees


  • To: Christian Lindig <christian.lindig@xxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Edwin Torok <edvin.torok@xxxxxxxxxx>
  • Date: Mon, 17 Aug 2020 18:46:36 +0000
  • Accept-language: en-GB, en-US
  • Authentication-results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none
  • Cc: Ian Jackson <Ian.Jackson@xxxxxxxxxx>, "dave@xxxxxxxxxx" <dave@xxxxxxxxxx>, "wl@xxxxxxx" <wl@xxxxxxx>
  • Delivery-date: Mon, 17 Aug 2020 18:46:43 +0000
  • Ironport-sdr: vMu41rJidYjrtdWv6dR4Bb0i1M5kRbtoSMPDXiIsWcV3v7/qKNs4uKfn0i9tnaPIHidMdYe+Ax VKKGzJ90MbfBDS3hwBodFicXPBL9D6hsw52EWrxsvqb3lUGYRNUcUcDLu7NzH4wA7fh/BjjXGZ TS3t3sJYvNVD+0emjxdNrF41DFm9iqpu1L44jFTkMmxPXY5EaGFBp0RW+Qbk9aEbr4ISBwI+TH 53XWN6lXioUvAV9N/5ChFdU/2PHJwNhdzU5twA7eWE+lac0ds1Zq1gU0/TPVIoJ+4p16CIy7PR ZUQ=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHWcohKODHsXl6Aq0qOV1QolADvZqk8I/0AgABi4wA=
  • Thread-topic: [PATCH v1 5/6] tools/ocaml/xenstored: use more efficient node trees

On Mon, 2020-08-17 at 14:52 +0200, Christian Lindig wrote:
> +let compare a b =
> +  if equal a b then 0
> +  else -(String.compare a b)
> 
> I think this bit could use an inline comment why the sort order is
> reversed. This could be also simplified to -(String.compare a b)
> because this goes to the internal (polymorphic) compare implemented
> in C which does a physical equivalence check first.

Good point, I've dropped the equal, and instead of negating the compare
I swapped its arguments.

See V3 of the patch (ignore V2, for some reason it looked nearly
identical to V1, not matching what I had in my git tree,
perhaps git-format-patch didn't overwrite the patches?).

Best regards,
--Edwin

> 
> -- C
> 
> ________________________________________
> From: Edwin Torok
> Sent: 14 August 2020 23:14
> To: xen-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: Edwin Torok; Christian Lindig; David Scott; Ian Jackson; Wei Liu
> Subject: [PATCH v1 5/6] tools/ocaml/xenstored: use more efficient
> node trees
> 
> This changes the output of xenstore-ls to be sorted.
> Previously the keys were listed in the order in which they were
> inserted
> in.
> docs/misc/xenstore.txt doesn't specify in what order keys are listed.
> 
> Map.update is used to retain semantics with replace_child:
> only an existing child is replaced, if it wasn't part of the original
> map we don't add it.
> Similarly exception behaviour is retained for del_childname and
> related
> functions.
> 
> Entries are stored in reverse sort order, so that upon Map.fold the
> constructed list is sorted in ascending order and there is no need
> for a
> List.rev.
> 
> Signed-off-by: Edwin Török <edvin.torok@xxxxxxxxxx>
> ---
>  tools/ocaml/xenstored/store.ml   | 46 +++++++++++++++---------------
> --
>  tools/ocaml/xenstored/symbol.ml  |  4 +++
>  tools/ocaml/xenstored/symbol.mli |  3 +++
>  3 files changed, 29 insertions(+), 24 deletions(-)
> 
> diff --git a/tools/ocaml/xenstored/store.ml
> b/tools/ocaml/xenstored/store.ml
> index 45659a23ee..d9dfa36045 100644
> --- a/tools/ocaml/xenstored/store.ml
> +++ b/tools/ocaml/xenstored/store.ml
> @@ -16,17 +16,19 @@
>   *)
>  open Stdext
> 
> +module SymbolMap = Map.Make(Symbol)
> +
>  module Node = struct
> 
>  type t = {
>         name: Symbol.t;
>         perms: Perms.Node.t;
>         value: string;
> -       children: t list;
> +       children: t SymbolMap.t;
>  }
> 
>  let create _name _perms _value =
> -       { name = Symbol.of_string _name; perms = _perms; value =
> _value; children = []; }
> +       { name = Symbol.of_string _name; perms = _perms; value =
> _value; children = SymbolMap.empty; }
> 
>  let get_owner node = Perms.Node.get_owner node.perms
>  let get_children node = node.children
> @@ -42,38 +44,34 @@ let set_value node nvalue =
>  let set_perms node nperms = { node with perms = nperms }
> 
>  let add_child node child =
> -       { node with children = child :: node.children }
> +       let children = SymbolMap.add child.name child node.children
> in
> +       { node with children }
> 
>  let exists node childname =
>         let childname = Symbol.of_string childname in
> -       List.exists (fun n -> Symbol.equal n.name childname)
> node.children
> +       SymbolMap.mem childname node.children
> 
>  let find node childname =
>         let childname = Symbol.of_string childname in
> -       List.find (fun n -> Symbol.equal n.name childname)
> node.children
> +       SymbolMap.find childname node.children
> 
>  let replace_child node child nchild =
> -       (* this is the on-steroid version of the filter one-replace
> one *)
> -       let rec replace_one_in_list l =
> -               match l with
> -               | []                               -> []
> -               | h :: tl when Symbol.equal h.name child.name ->
> nchild :: tl
> -               | h :: tl                          -> h ::
> replace_one_in_list tl
> -               in
> -       { node with children = (replace_one_in_list node.children) }
> +       { node with
> +         children = SymbolMap.update child.name
> +                    (function None -> None | Some _ -> Some nchild)
> +                    node.children
> +       }
> 
>  let del_childname node childname =
>         let sym = Symbol.of_string childname in
> -       let rec delete_one_in_list l =
> -               match l with
> -               | []                        -> raise Not_found
> -               | h :: tl when Symbol.equal h.name sym -> tl
> -               | h :: tl                   -> h ::
> delete_one_in_list tl
> -               in
> -       { node with children = (delete_one_in_list node.children) }
> +       { node with children =
> +               SymbolMap.update sym
> +                 (function None -> raise Not_found | Some _ -> None)
> +                 node.children
> +       }
> 
>  let del_all_children node =
> -       { node with children = [] }
> +       { node with children = SymbolMap.empty }
> 
>  (* check if the current node can be accessed by the current
> connection with rperm permissions *)
>  let check_perm node connection request =
> @@ -87,7 +85,7 @@ let check_owner node connection =
>                 raise Define.Permission_denied;
>         end
> 
> -let rec recurse fct node = fct node; List.iter (recurse fct)
> node.children
> +let rec recurse fct node = fct node; SymbolMap.iter (fun _ ->
> recurse fct) node.children
> 
>  let unpack node = (Symbol.to_string node.name, node.perms,
> node.value)
> 
> @@ -321,7 +319,7 @@ let ls store perm path =
>                                 Node.check_perm cnode perm
> Perms.READ;
>                                 cnode.Node.children in
>                         Path.apply store.root path do_ls in
> -       List.rev (List.map (fun n -> Symbol.to_string n.Node.name)
> children)
> +       SymbolMap.fold (fun k _ accu -> Symbol.to_string k :: accu)
> children []
> 
>  let getperms store perm path =
>         if path = [] then
> @@ -350,7 +348,7 @@ let traversal root_node f =
>         let rec _traversal path node =
>                 f path node;
>                 let node_path = Path.of_path_and_name path
> (Symbol.to_string node.Node.name) in
> -               List.iter (_traversal node_path) node.Node.children
> +               SymbolMap.iter (fun _ -> _traversal node_path)
> node.Node.children
>                 in
>         _traversal [] root_node
> 
> diff --git a/tools/ocaml/xenstored/symbol.ml
> b/tools/ocaml/xenstored/symbol.ml
> index dac6f9f819..2697915623 100644
> --- a/tools/ocaml/xenstored/symbol.ml
> +++ b/tools/ocaml/xenstored/symbol.ml
> @@ -31,6 +31,10 @@ let equal a b =
>    (* compare using physical equality, both members have to be part
> of the above weak table *)
>    a == b
> 
> +let compare a b =
> +  if equal a b then 0
> +  else -(String.compare a b)
> +
>  let stats () =
>    let len, entries, _, _, _, _ = WeakTable.stats tbl in
>    len, entries
> diff --git a/tools/ocaml/xenstored/symbol.mli
> b/tools/ocaml/xenstored/symbol.mli
> index 586ab57507..dd0f014796 100644
> --- a/tools/ocaml/xenstored/symbol.mli
> +++ b/tools/ocaml/xenstored/symbol.mli
> @@ -32,6 +32,9 @@ val to_string : t -> string
>  val equal: t -> t -> bool
>  (** Compare two symbols for equality *)
> 
> +val compare: t -> t -> int
> +(** Compare two symbols *)
> +
>  (** {6 Statistics } *)
> 
>  val stats : unit -> int * int
> --
> 2.25.1
> 

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.