Memcached クライアント
get, set, add, delete を実装した。機能的にはまだまだなところがあるけれど、それはおいおいってことで。
何かを作りながら、学んでいくのも悪くはない。本を読み上げるという目標だけだと、やる気がわかないんだよね、僕は。
(***********************************************************************) (* *) (* Memcached Client library module *) (* *) (***********************************************************************) (* * supported plan: * "set", "add", "replace" * "get" and "gets" * "delete" * "incr" and "decr" *) #load "unix.cma";; #load "str.cma";; module Memcache = struct type t = { mutable hostname : string; mutable port : int ; mutable sock : Unix.file_descr; } let version = "0.0.1" let ends_with s suff = if String.length(s) < String.length(suff) then false else let suff_len = String.length suff in let s_suffix = String.sub s ((String.length s) - suff_len) suff_len in if String.compare s_suffix suff == 0 then true else false let tcp_recv sock = let response = Buffer.create 256 in let buff = String.create 128 in let rec read_loop () = let r = Unix.read sock buff 0 127 in if r < 1 then () else ( Buffer.add_string response (String.sub buff 0 r); if ends_with (Buffer.contents response) "\r\n" then ( (); ) else ( read_loop (); ) ) in read_loop (); Buffer.contents response let open_connection hostname port = Printf.printf "<open_connection> %s:%d\n" hostname port; let conn = { hostname = hostname; port = port; sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0; } in let haddr = Unix.gethostbyname conn.hostname in Unix.connect conn.sock (Unix.ADDR_INET(haddr.Unix.h_addr_list.(0), conn.port)); conn let get self key = Printf.printf "<get> key=[%s]\n" key; let request = Printf.sprintf "get %s\r\n" key in let r = Unix.write self.sock request 0 (String.length request) in if r < 0 then "" else let res = tcp_recv self.sock in let reg = Str.regexp "VALUE \\([^ ]+?\\) \\([^ ]+?\\) \\([^ ]+?\\)\\([^\r\n]*\\)\r\n\\(.+?\\)\r\nEND\r\n" in let r = Str.string_match reg res 0 in if r == false then "" else Str.matched_group 5 res let set self key value = Printf.printf "<set> key=[%s], value=[%s]\n" key value; let request = Printf.sprintf "set %s 0 0 %d\r\n%s\r\n" key (String.length value) value in let r = Unix.write self.sock request 0 (String.length request) in if r < 0 then () else let res = tcp_recv self.sock in Printf.printf "<get> response: [%s]\n" res; () let add self key value = Printf.printf "<add> key=[%s], value=[%s]\n" key value; let request = Printf.sprintf "add %s 0 0 %d\r\n%s\r\n" key (String.length value) value in let r = Unix.write self.sock request 0 (String.length request) in if r < 0 then () else let res = tcp_recv self.sock in Printf.printf "<add> response: [%s]\n" res; () let delete self key = Printf.printf "<delete> key=[%s]\n" key; let request = Printf.sprintf "delete %s\r\n" key in let r = Unix.write self.sock request 0 (String.length request) in if r < 0 then () else let res = tcp_recv self.sock in let reg = Str.regexp "^DELETED" in let r = Str.string_match reg res 0 in if r == false then () else () let close_connection self = Printf.printf "<close_connection>\n"; Unix.shutdown self.sock Unix.SHUTDOWN_ALL; Unix.close self.sock end ;; let _ = Printf.printf "version: %s\n" Memcache.version; let cache = Memcache.open_connection "localhost" 11211 in Memcache.set cache "foo" "bar"; Memcache.add cache "foo01" "abcdefg"; Memcache.set cache "foo01" "bar"; let value = Memcache.get cache "foo" in Printf.printf "foo = %s\n" value; Memcache.delete cache "foo"; let value = Memcache.get cache "foo" in Printf.printf "foo = %s\n" value; Memcache.close_connection cache; exit 0;