user130532
user130532

Reputation:

How can I improve this implementation to be more efficient

I have a service method that needs to process an incoming object: (by the way, this is pseudo code)

public class IncomingParentObject {
    public Collection<IncomingChildOject> childObjects; 
}

public Class IncmoingChildObject {
    public String name;
}

I have a "registry" of "clients" that care about a subset of the incoming child objects. At the point of registration we only know about the "name". The client object encapsulates details for the transport layer to forward information to.

public class Registry {
    // String represents the name in the child object
    public Map<String, Set<Client>> clients;
}

Right now the service class is something along the lines of this:

public void processIncmoingParentObject(IncomingParentObject parentObject) {
    for (IncmoingChildObject childObject : parentObject.childObjects) {
        Set<Client> clients = registry.clients.get(childObject.name);

        for (Client client : clients) {
            this.transportLayer.transportChildObject(childObject, client);
        }
    }
}

This results in several calls to the transportLayer (which may be expensive or timely). I want to reduce this to basically one transport per client of a subset of ChildObjects.

transportLayer.transport(Client client, Set<IncmoingChildObject> childObjects);

What would an effiecent manor be to scan through the parents children to determine a subset of children to send to a client.

Upvotes: 3

Views: 105

Answers (2)

NPE
NPE

Reputation: 500873

I'd use a map to keep track of Set<IncomingChildObject> for each Client.

In untested Java:

public void processIncomingParentObject(IncomingParentObject parentObject) {
    Map<Client,Set<IncomingChildObject>> childObjectsByClient =
        new Map<Client,Set<IncomingChildObject>>();
    for (IncomingChildObject childObject : parentObject.childObjects) {
        Set<Client> clients = registry.clients.get(childObject.name);
        for (Client client : clients) {
            Set<IncomingChildObject> childObjects =
                childObjectsByClient.get(client);
            if (childObjects == null) {
                childObjects = new Set<IncomingChildObject>();
                childObjectsByClient.put(client, childObjects);
            }
            childObjects.add(childObject);
        }
    }
    for (Entry<Client,Set<IncomingChildObject>> e : childObjectsByClient.entrySet()) {
        this.transportLayer.transport(e.getKey(), e.getValue());
    }
}

Upvotes: 2

Thomas
Thomas

Reputation: 88747

Well, you could build a map name -> list of children and then iterate over the list and get the client for each key in the map. Then pass that client and the list of children for the map entry to the transport layer.

For this you could try and use one of the Multimap implementations in the Apache Commons Collections project (it doesn't support generics but there's a third party port that does, alternatively try Google Guava, although I don't know whether it provides a multimap).

Upvotes: 0

Related Questions