code: def query(self, keys, k):
      if not self.has_enough_entries(k):
          # this will only happen when the DND is not yet populated with enough entries, which is only during heatup
          # these values won't be used and therefore they are meaningless
          return [0.0], [0.0], [0], [None]
  
      _, indices = self._get_k_nearest_neighbors_indices(keys, k)
  
      embeddings = []
      values = []
      additional_data = []
      for ind in indices:
          self.lru_timestamps[ind] = self.current_timestamp
          embeddings.append(self.embeddings[ind])
          values.append(self.values[ind])
          curr_additional_data = []
          for sub_ind in ind:
              curr_additional_data.append(self.additional_data[sub_ind])
          additional_data.append(curr_additional_data)
  
      self.current_timestamp += 1
  
      return embeddings, values, indices, additional_data
  
imports: import os
  import pickle
  import numpy
label_desc: Use image node_id 3 for calling the AnnoyDictionary obj's underlying member method code with example usage: obj.query(keys, k) and returns: embeddings,  values,  indices,  additional_data, list,  list,  list,  list