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

[Xen-devel] [PATCH 5/8] oxenstored: use hash table to store socket connections



Currently we use list to store socket connections. This is fine for smaller
number of connections. But when we scale up, traveling through a list of
hundreds or thousands of connections just to find a single one of them is very
low efficient.

This patch replaces the list with a (Unix.file_descr -> Connection.t) hash 
table.

Signed-off-by: Zheng Li <dev@xxxxxxxx>
---
 tools/ocaml/xenstored/connections.ml | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml 
b/tools/ocaml/xenstored/connections.ml
index f4550f9..59c5c1a 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -18,17 +18,17 @@
 let debug fmt = Logging.debug "connections" fmt
 
 type t = {
-       mutable anonymous: Connection.t list;
+       anonymous: (Unix.file_descr, Connection.t) Hashtbl.t;
        domains: (int, Connection.t) Hashtbl.t;
        mutable watches: (string, Connection.watch list) Trie.t;
 }
 
-let create () = { anonymous = []; domains = Hashtbl.create 8; watches = 
Trie.create () }
+let create () = { anonymous = Hashtbl.create 37; domains = Hashtbl.create 37; 
watches = Trie.create () }
 
 let add_anonymous cons fd can_write =
        let xbcon = Xenbus.Xb.open_fd fd in
        let con = Connection.create xbcon None in
-       cons.anonymous <- con :: cons.anonymous
+       Hashtbl.add cons.anonymous (Xenbus.Xb.get_fd xbcon) con
 
 let add_domain cons dom =
        let xbcon = Xenbus.Xb.open_mmap (Domain.get_interface dom) (fun () -> 
Domain.notify dom) in
@@ -36,14 +36,14 @@ let add_domain cons dom =
        Hashtbl.add cons.domains (Domain.get_id dom) con
 
 let select cons =
-       let inset = List.map (fun c -> Connection.get_fd c) cons.anonymous
-       and outset = List.fold_left (fun l c -> if Connection.has_output c
-                                               then Connection.get_fd c :: l
-                                               else l) [] cons.anonymous in
-       inset, outset
+       Hashtbl.fold
+               (fun _ con (ins, outs) ->
+                let fd = Connection.get_fd con in
+                (fd :: ins,  if Connection.has_output con then fd :: outs else 
outs))
+               cons.anonymous ([], [])
 
-let find cons fd =
-       List.find (fun c -> Connection.get_fd c = fd) cons.anonymous
+let find cons =
+       Hashtbl.find cons.anonymous
 
 let find_domain cons id =
        Hashtbl.find cons.domains id
@@ -55,7 +55,7 @@ let del_watches_of_con con watches =
 
 let del_anonymous cons con =
        try
-               cons.anonymous <- Utils.list_remove con cons.anonymous;
+               Hashtbl.remove cons.anonymous (Connection.get_fd con);
                cons.watches <- Trie.map (del_watches_of_con con) cons.watches;
                Connection.close con
        with exn ->
@@ -74,7 +74,7 @@ let iter_domains cons fct =
        Hashtbl.iter (fun k c -> fct c) cons.domains
 
 let iter_anonymous cons fct =
-       List.iter (fun c -> fct c) (List.rev cons.anonymous)
+       Hashtbl.iter (fun _ c -> fct c) cons.anonymous
 
 let iter cons fct =
        iter_domains cons fct; iter_anonymous cons fct
@@ -163,10 +163,10 @@ let stats cons =
                nb_ops_dom := !nb_ops_dom + con_ops;
                nb_watchs_dom := !nb_watchs_dom + con_watchs;
        );
-       (List.length cons.anonymous, !nb_ops_anon, !nb_watchs_anon,
-        Hashtbl.length cons.domains, !nb_ops_dom, !nb_watchs_dom)
+       (Hashtbl.length cons.anonymous, !nb_ops_anon, !nb_watchs_anon,
+        Hashtbl.fold (fun k _ a -> if k > 0 then a+1 else a) cons.domains 0, 
!nb_ops_dom, !nb_watchs_dom)
 
 let debug cons =
-       let anonymous = List.map Connection.debug cons.anonymous in
+       let anonymous = Hashtbl.fold (fun _ con accu -> Connection.debug con :: 
accu) cons.anonymous [] in
        let domains = Hashtbl.fold (fun _ con accu -> Connection.debug con :: 
accu) cons.domains [] in
        String.concat "" (domains @ anonymous)
-- 
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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