(* Copyright 2012 Gerd Stolpmann This file is part of Plasma, a distributed filesystem and a map/reduce computation framework. Unless you have a written license agreement with the copyright holder (Gerd Stolpmann), the following terms apply: Plasma is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Plasma is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Plasma. If not, see <http://www.gnu.org/licenses/>. *) (* $Id: mapred_rfun.ml 561 2012-01-06 00:34:10Z gerd $ *) open Printf type 't rfun = | Rfun of string | Apply of Obj.t * (Obj.t->Obj.t) rfun constraint 't = _ -> _ exception Rfun_not_found of string let tab = (Hashtbl.create 19 : (string, Obj.t -> Obj.t) Hashtbl.t) ;; let finished = ref false let p4_file = ref None let p4_prefix = ref None let register name f = if !finished then failwith "Mapred_rfun: it is too late for registering a function"; if Hashtbl.mem tab name then failwith "Mapred_rfun: the name is already used"; Hashtbl.add tab name (Obj.magic f); Rfun name let finish() = finished := true let rec lookup_i rf = match rf with | Rfun name -> ( try let f = Hashtbl.find tab name in f with | Not_found -> raise(Rfun_not_found name) ) | Apply(x,rf') -> let f = lookup_i rf' in (Obj.magic f : _ -> _) x let lookup = ( fun rf -> Obj.magic (lookup_i (Obj.magic rf)) : ('a -> 'b) rfun -> 'a -> 'b ) let rec get_id_i rf = match rf with | Rfun id -> id | Apply(_,rf) -> get_id_i rf let get_id = ( fun rf -> get_id_i (Obj.magic rf) : ('a -> 'b) rfun -> string ) let apply_partially rf x = Apply(Obj.magic x, Obj.magic rf) let p4_new_file get_loc = let file = try get_loc(); failwith "Mapred_rfun.p4_new_file" with | Assert_failure(file,_,_) -> file in p4_file := Some file; p4_prefix := Some(Digest.to_hex(Digest.string (file (* ^ "/" ^ string_of_float (Unix.gettimeofday()) *) ))) let p4_register get_loc f = if !finished then failwith "Mapred_rfun: it is too late for registering a function"; let (file, line, col) = try get_loc(); failwith "Mapred_rfun.p4_new_file" with | Assert_failure(file,line,col) -> (file,line,col) in if !p4_file <> Some file then failwith "Mapred_rfun.p4_register"; let prefix = match !p4_prefix with | None -> assert false | Some p -> p in register (sprintf "%s_%d_%d" prefix line col) f