Home > Back-end >  How to check contents of one list with multiple lists
How to check contents of one list with multiple lists

Time:06-12

Here is a list created from YAML file. I want to compare the following contents of each individual lists with other lists:

  1. Two memory servers should not have same ip:port combination
  2. Two memory servers hosted from same machine, should not have same path
  3. Two memory servers hosted from same machine, should not have same libfabric port

The code should be generic i.e., it should work for any number of servers.

0:
  memory_type: volatile
  fam_path: /dev/shm/vol_path
  rpc_interface: fam5:8793
  libfabric_port: 7500
  if_device: eth0
1:
  memory_type: volatile
  fam_path: /dev/shm/vol_path
  rpc_interface: fam3:8793
  libfabric_port: 7500
  if_device: eth1
2:
  memory_type: volatile
  fam_path: /dev/shm/vol_path
  rpc_interface: fam3:8793
  libfabric_port: 7500
  if_device: eth1
3:
  memory_type: volatile
  fam_path: /dev/shm/vol_path
  rpc_interface: fam6:8793
  libfabric_port: 7500
  if_device: eth1
4:
  memory_type: volatile
  fam_path: /dev/shm/vol_path
  rpc_interface: fam7:8793
  libfabric_port: 7500
  if_device: eth1
5:
  memory_type: volatile
  fam_path: /dev/shm/vol_path
  rpc_interface: fam8:8793
  libfabric_port: 7500
  if_device: eth1
6:
  memory_type: volatile
  fam_path: /dev/shm/vol_path
  rpc_interface: fam9:8793
  libfabric_port: 7500
  if_device: eth1
7:
  memory_type: volatile
  fam_path: /dev/shm/vol_path
  rpc_interface: fam10:8793
  libfabric_port: 7500
  if_device: eth1

The one i have done so far checks between all the files. But I want it only between two files.

import yaml
def compare():
    try:
        #creates list
        data= open(r"C:\Users\User\OneDrive\Documents\HPE\Task 1\tools-main\tools-main\config\fam_memoryserver_config.yaml", 'r')
        parsed_yaml=yaml.safe_load(data)
        print(parsed_yaml)
        print('The length of list is %d'  %int(len(parsed_yaml)))#Calculates the number of lists(memory_server_id) available
        mysets = (set(x.items()) for x in parsed_yaml.values())
        K=reduce(lambda a,b: a.intersection(b), mysets)
        print('The conditions that are same is\n%s' % str(K))
    except Exception as exc:
        print('The error is\n%s' % str(exc))

compare()

CodePudding user response:

For each of your requirements, you should just map the value (that should not duplicate) to the machine numbers that you found them in. In the following just done for the first requirement:

from pathlib import Path
import ruamel.yaml

host_port = {}
file_in = Path('fam_memoryserver_config.yaml')

yaml = ruamel.yaml.YAML(typ='safe')  # faster than using yaml.safe_load()
data = yaml.load(file_in)
for machine_nr, config in data.items():
    host_port.setdefault(config['rpc_interface'], set()).add(machine_nr)

# now check if host_port has any values that have more than one machine_nr
for hp, machine_nrs in host_port.items():
    if len(machine_nrs) == 1:
        continue
    print(f'found {hp} in machines: {", ".join([str(x) for x in machine_nrs])}')

which gives:

found fam3:8793 in machines: 1, 2

You should get your terminology clear, or at least define these in your question. Common terminology will help you find answers yourself more easily (here on SO, or googling).

You don't have any lists, you have a mapping at the root level of your YAML document, with mapping for the values of each key. Those load to dicts nested within a dict. there are no lists anywhere.

The above also assumes that the value for key rpc_interfaces is what you refer to as ip:port, however that part before the : in fam5:8793 doesn't look like an IPv4 or an IPv6 address. It looks more like a hostname.

You also refer to checks between all files, but there are only two files: the YAML input and your source code. And comparing between those doesn't make much sense.

  • Related