code: def get_neighbour_keys(self, bucket_key, k):
          
          # convert query_key into bitarray
          query_key = bitarray(bucket_key)
  
          topk = set()
          for i in xrange(len(self.permutes)):
              p = self.permutes[i]
              plist = self.permuted_lists[i]
              candidates = p.search_revert(plist, query_key, self.beam_size)
              topk = topk.union(set(candidates))
          topk = list(topk)
  
          # sort the topk neighbour keys according to the Hamming distance to qurey key
          topk = sorted(topk, key=lambda x: self.hamming_distance(x, query_key))
          # return the top k items
          topk_bin = [x.to01() for x in topk[:k]]
          return topk_bin
docs: The computing complexity is O( np*beam*log(np*beam) )
          where,
          np = number of permutations
          beam = self.beam_size
  
          Make sure np*beam is much less than the number of bucket keys,
          otherwise we could use brute-force to get the neighbours