<commit_before>(*
Copyright (C) 2016 iNuron NV

This file is part of Open vStorage Open Source Edition (OSE), as available from


    http://www.openvstorage.org and
    http://www.openvstorage.com.

This file is free software; you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License v3 (GNU AGPLv3)
as published by the Free Software Foundation, in version 3 as it comes
in the <LICENSE.txt> file of the Open vStorage OSE distribution.

Open vStorage is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY of any kind.
*)

open Prelude
open Lwt.Infix

type bucket_safety = {
    bucket : (int * int * int * int);
    count  : int64;
    applicable_dead_osds : int;
    remaining_safety : int;
  } [@@deriving show, yojson]

let get_namespace_safety
      (alba_client : Alba_client.alba_client)
      ns_info dead_ns_osds =
  let open Albamgr_protocol.Protocol in
  let open Nsm_model in
  let namespace_id = ns_info.Namespace.id in

  Lwt_list.map_p
    (fun osd_id ->
       alba_client # osd_access # get_osd_info ~osd_id >>= fun (osd_info, _, _) ->
       Lwt.return (osd_id, osd_info.OsdInfo.node_id))
    dead_ns_osds
  >>= fun osds_with_node_id ->

  alba_client # nsm_host_access # get_nsm_by_id ~namespace_id >>= fun nsm ->

  nsm # get_stats >>= fun { Nsm_model.NamespaceStats.bucket_count; } ->
  let res =
    List.filter
      (fun (policy, cnt) -> Int64.(cnt >: 0L))
      (snd bucket_count) |>
    List.map
      (fun (bucket, count) ->
         let k, m, fragment_count, max_disks_per_node = bucket in
         let applicable_dead_osds =
           Policy.get_applicable_osd_count
             max_disks_per_node
             osds_with_node_id
         in
         { bucket;
           count;
           applicable_dead_osds;
           remaining_safety = (fragment_count-k) - applicable_dead_osds;
         }
      ) |>
    List.sort
      (fun s1 s2 -> compare s1.remaining_safety s2.remaining_safety)
  in

  Lwt.return res


let get_disk_safety alba_client namespaces dead_osds =

  (* remove any duplicates *)
  let dead_osds = List.sort_uniq compare dead_osds in

  Lwt_list.map_p
    (fun osd_id ->
       alba_client # mgr_access # list_all_osd_namespaces ~osd_id
       >>= fun (_, osd_namespaces) ->
       let r =
         List.map
           (fun namespace_id -> (osd_id, namespace_id))
           osd_namespaces
       in
       Lwt.return r)
    dead_osds<commit_msg>disk safety smaller than -k makes no sense<commit_after>(*
Copyright (C) 2016 iNuron NV

This file is part of Open vStorage Open Source Edition (OSE), as available from


    http://www.openvstorage.org and
    http://www.openvstorage.com.

This file is free software; you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License v3 (GNU AGPLv3)
as published by the Free Software Foundation, in version 3 as it comes
in the <LICENSE.txt> file of the Open vStorage OSE distribution.

Open vStorage is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY of any kind.
*)

open Prelude
open Lwt.Infix

type bucket_safety = {
    bucket : (int * int * int * int);
    count  : int64;
    applicable_dead_osds : int;
    remaining_safety : int;
  } [@@deriving show, yojson]

let get_namespace_safety
      (alba_client : Alba_client.alba_client)
      ns_info dead_ns_osds =
  let open Albamgr_protocol.Protocol in
  let open Nsm_model in
  let namespace_id = ns_info.Namespace.id in

  Lwt_list.map_p
    (fun osd_id ->
       alba_client # osd_access # get_osd_info ~osd_id >>= fun (osd_info, _, _) ->
       Lwt.return (osd_id, osd_info.OsdInfo.node_id))
    dead_ns_osds
  >>= fun osds_with_node_id ->

  alba_client # nsm_host_access # get_nsm_by_id ~namespace_id >>= fun nsm ->

  nsm # get_stats >>= fun { Nsm_model.NamespaceStats.bucket_count; } ->
  let res =
    List.filter
      (fun (policy, cnt) -> Int64.(cnt >: 0L))
      (snd bucket_count) |>
    List.map
      (fun (bucket, count) ->
         let k, m, fragment_count, max_disks_per_node = bucket in
         let applicable_dead_osds =
           Policy.get_applicable_osd_count
             max_disks_per_node
             osds_with_node_id
         in
         { bucket;
           count;
           applicable_dead_osds;
           remaining_safety = max ((fragment_count-k) - applicable_dead_osds) (-k);
         }
      ) |>
    List.sort
      (fun s1 s2 -> compare s1.remaining_safety s2.remaining_safety)
  in

  Lwt.return res


let get_disk_safety alba_client namespaces dead_osds =

  (* remove any duplicates *)
  let dead_osds = List.sort_uniq compare dead_osds in

  Lwt_list.map_p
    (fun osd_id ->
       alba_client # mgr_access # list_all_osd_namespaces ~osd_id
       >>= fun (_, osd_namespaces) ->
       let r =
         List.map
           (fun namespace_id -> (osd_id, namespace_id))
           osd_namespaces
       in
       Lwt.return r)
    dead_osds
{'fraction_non_alphanumeric': 0.0810483870967742, 'fraction_numerical': 0.0064516129032258064, 'mean_word_length': 2.6639586410635157, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, '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': '1171881', 'n_tokens_mistral': 1753, 'n_tokens_neox': 1696, 'n_words': 470}