class_docstr: HistogramIndexer is used to index the `VectorizedHistogram` data.
  
  The data is stored in a flatten array with the shape is (num_node * sum(feature_bin_sizes)) and the
  data is indexed by (node_id, feature_id, bin_id) in the flatten array.
  At logical level, the data is indexed by (node_id, feature_id, bin_id) likes:
  
  node_id_0:
      feature_id_0:
          bin_id_0: data
          bin_id_1: data
          ...
      feature_id_1:
          bin_id_0: data
          bin_id_1: data
          ...
      ...
  node_id_1:
      feature_id_0:
          bin_id_0: data
          bin_id_1: data
          ...
      feature_id_1:
          bin_id_0: data
          bin_id_1: data
          ...
      ...
  ...
  notice that the data is stored in the flatten array, so the index is calculated by:
      position = node_id * sum(feature_bin_sizes) + feature_bin_sizes[feature_id] + bin_id
  
  which means the bin_size of each feature is not necessary to be the same but the sum of all feature_bin_sizes
  should be the same.
  
  Notes: This class will be rewritten in rust in the future.
docstr: get data positions by node_ids and bin_ids
  Args:
      nids: node ids
      bids: bin ids
      node_mapping: node mapping
  
  Returns: data positions
docstr_tok: ["get","data","positions","by","node_ids","and","bin_ids","Args",":","nids",":","node","ids","bids",":","bin","ids","node_mapping",":","node","mapping","Returns",":","data","positions"]
code: def get_positions_with_node_mapping(
      self,
      nids: List[int],
      bids: List[List[int]],
      node_mapping: Dict[int, int],
  ):
      """
      get data positions by node_ids and bin_ids
      Args:
          nids: node ids
          bids: bin ids
          node_mapping: node mapping
  
      Returns: data positions
      """
      assert len(nids) == len(
          bids
      ), f"nids length {len(nids)} is not equal to bids length {len(bids)}"
      positions = []
      masks = []
      for nid, bids in zip(nids, bids):
          if nid in node_mapping:
              positions.append(
                  [
                      self.get_position(node_mapping[nid], fid, bid)
                      for fid, bid in enumerate(bids)
                  ]
              )
              masks.append(True)
          else:
              masks.append(False)
      return positions, masks
  
imports: from typing import List, Tuple, Dict
  import numpy
  import torch
label_desc: Use image node_id 5 for calling the HistogramIndexer obj's underlying member method code with example usage: obj.get_positions_with_node_mapping(nids, bids, node_mapping) and returns: positions,  masks