<commit_before>let try_times n ~f =
  assert (n > 0);
  let rec loop n =
    if n = 1 then
      f n
    else
      match f n with
      | exception _ -> loop (n - 1)
      | r -> r
  in
  loop n

let prng = lazy (Random.State.make_self_init ())

let temp_file_name ?temp_dir ~prefix ~suffix () =
  let temp_dir =
    match temp_dir with
    | None -> Filename.get_temp_dir_name ()
    | Some t -> t
  in
  let rnd = Random.State.bits (Lazy.force prng) land 0xFFFFFF in
  Filename.concat temp_dir (Printf.sprintf "%s%06x%s" prefix rnd suffix)

let tmp_files = ref Path.Set.empty

let tmp_dirs = ref Path.Set.empty

external open_desc : string -> open_flag list -> int -> int = "caml_sys_open"

external close_desc : int -> unit = "caml_sys_close"

let create_temp_file name =
  close_desc (open_desc name [ Open_wronly; Open_creat; Open_excl ] 0o600)

let create_temp_dir name =
  match Fpath.mkdir_p name with
  | Created -> ()
  | Already_exists -> failwith "temp dir exists"

let () =
  let iter_and_clear r ~f =
    let tmp = !r in
    r := Path.Set.empty;
    Path.Set.iter tmp ~f
  in
  at_exit (fun () ->
      iter_and_clear tmp_files ~f:Path.unlink_no_err;
      iter_and_clear tmp_dirs ~f:(Path.rm_rf ~allow_external:true))

let temp ~set ~prefix ~suffix ~create =
  let path =
    try_times 1000 ~f:(fun _ ->
        let name = temp_file_name ~prefix ~suffix () in
        create name;
        name)
    |> Path.of_string
  in
  set := Path.Set.add !set path;
  path
<commit_msg>Improve error message if temp_dir fails<commit_after>let try_times n ~f =
  assert (n > 0);
  let rec loop n =
    if n = 1 then
      f n
    else
      match f n with
      | exception _ -> loop (n - 1)
      | r -> r
  in
  loop n

let prng = lazy (Random.State.make_self_init ())

let temp_file_name ?temp_dir ~prefix ~suffix () =
  let temp_dir =
    match temp_dir with
    | None -> Filename.get_temp_dir_name ()
    | Some t -> t
  in
  let rnd = Random.State.bits (Lazy.force prng) land 0xFFFFFF in
  Filename.concat temp_dir (Printf.sprintf "%s%06x%s" prefix rnd suffix)

let tmp_files = ref Path.Set.empty

let tmp_dirs = ref Path.Set.empty

external open_desc : string -> open_flag list -> int -> int = "caml_sys_open"

external close_desc : int -> unit = "caml_sys_close"

let create_temp_file name =
  close_desc (open_desc name [ Open_wronly; Open_creat; Open_excl ] 0o600)

let create_temp_dir name =
  match Fpath.mkdir_p name with
  | Created -> ()
  | Already_exists -> raise (Unix.Unix_error (ENOENT, "mkdir", name))

let () =
  let iter_and_clear r ~f =
    let tmp = !r in
    r := Path.Set.empty;
    Path.Set.iter tmp ~f
  in
  at_exit (fun () ->
      iter_and_clear tmp_files ~f:Path.unlink_no_err;
      iter_and_clear tmp_dirs ~f:(Path.rm_rf ~allow_external:true))

let temp ~set ~prefix ~suffix ~create =
  let path =
    try_times 1000 ~f:(fun _ ->
        let name = temp_file_name ~prefix ~suffix () in
        create name;
        name)
    |> Path.of_string
  in
  set := Path.Set.add !set path;
  path

{'fraction_non_alphanumeric': 0.10670630987776676, 'fraction_numerical': 0.009250082590023126, 'mean_word_length': 2.7568238213399505, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3993137', 'n_tokens_mistral': 1150, 'n_tokens_neox': 1111, 'n_words': 328}