0

Given 2 objects / classes:

  • A class for a cargo ship. It has a small set of attributes, say current location, size, number of crew and some other things. Most important, it has an attribute for the id which is unique and the class is hashable.
  • A class for a harbor. Again a small list of attributes like location and the unique identifier. This class is hashable as well.

Now you could ask interesting questions like:

  1. For each cargo ship what is the nearest harbor together with its distance.
  2. For each harbor give me a list of all cargo ships within a 100 km radius.
  3. Give me for each cargo ship a list of all harbors visited last year (you probably need some extra info for this question, but this detail we omit for now as it is about the results).

Next let's assume classes are immutable. All classes are in computer memory too.

Now my question is how to store the results of given questions in memory? Should I for each question only keep the relations between the id's (which each cargo ship and harbor has) or can I keep the entire classes which should work because they are hashable?

A small example for question 2:

When I only keep id's it could look like this:

{5235: [735235, 25245, 954646],

3232: [112, 34345, 65354, 45454]}

Or should it be like this:

{(an entire harbor class): [(an entire ship class), (an entire ship class) , (an entire ship class)],

(an entire harbor class): [(an entire ship class), (an entire ship class), (an entire ship class), (an entire ship class)]}

(While writing this I came up with another question, should the unique identifier be an attribute of the class, I mean every question you ask has strictly nothing to do with the identifier)

4
  • 2
    I vast majority languages both options are equal - the "entire class" is effectively integer anyways, a pointer/reference on heap. The only difference I see when you are dealing with some special kind of technology when those are not equal or when dealing with cached / volatile (or db backed with multiple r/w clients) versions of classes and you need reactive results. Is any of above your case?
    – wondra
    Commented Jan 29, 2018 at 7:11
  • @wondra Yes I understand, thanks. There is hardly any difference at all however I was still wondering if one solution would be preferred over the other one from a software engineering point of view.
    – Elmex80s
    Commented Jan 29, 2018 at 9:37
  • Well, as implied, there is the difference in enforcing re-query (lookup of instances) when using IDs. This allows invalidating caches or similar logic hooked on querying instance by ID. What you should do depends on your particular case though, however using built-in references is probably simpler than rolling your own.
    – wondra
    Commented Jan 29, 2018 at 10:19
  • 1
    Typically if the only way to access the results through the IDs is through the hash table, the object reference/pointer would be a lot more efficient. Hash table looks up are constant-time but they're not the cheapest of constants, relatively speaking, compared to, say, dereferencing a pointer or indexing an array. Not necessarily suggesting that efficiency should be your guide here, but if it can go either way, at least the object refs/pointers have that added benefit.
    – user204677
    Commented Jan 29, 2018 at 11:23

2 Answers 2

1

Should I for each question only keep the relations between the id's (which each cargo ship and harbor has) or can I keep the entire classes which should work because they are hashable?

Because it sounds like ships will be moving around and thus the data stored in your map will be changing frequently, it is probably more efficient to store only their IDs in the map (and store the ship/harbor instances elsewhere where you can look them up by ID when needed). When you store a ship/harbor instance in the map, rehashes will be more expensive since the entire (potentially large) object would need to be copied into its new location.

should the unique identifier be an attribute of the class, I mean every question you ask has strictly nothing to do with the identifier

This depends on whether the ship/harbor needs to know its own ID or whether you might ever need to figure out an ID given only the ship/harbor. If either of these are true, it's probably easiest to store the ID as a member of the class. If not, then you could simply store it as the keys used for looking up the objects, but not in the objects themselves.


It's difficult to give a definite answer to either of these questions without knowing/considering all of the other design parameters for this project and the way you may want to change these features in the future.

2
  • 1
    Thanks, but as I said the classes are immutable. Say you have a snap-shot of all ships.
    – Elmex80s
    Commented Jan 28, 2018 at 23:39
  • Apologies, missed that. In that case, it doesn't really matter either way. The benefit to storing them in one way or another has to do with how you might change the map. But if the data never changes then it's irrelevant.
    – yoyoyango
    Commented Jan 28, 2018 at 23:48
1

Now you could ask interesting questions like:

  • For each harbor give me a list of all cargo ships within a 100 km radius.

how to store the results of given questions in memory?

Ok, so, you're working with objects in memory. As reasonable return type is an one of the following types, here in n C#:

Dictionary<Harbor,HashSet<Ship>>                      // concrete collection
IDictionary<Harbor,ICollection<Ship>>                 // interface-based collection
IReadOnlyDictionary<Harbor,IReadOnlyCollection<Ship>> // interface-based, immutable
IEnumerable<KeyValuePair<Harbor,IEnumerable<Ship>>    // enumerable-based collection

Java has similar equivalents.

Should I only keep the relations between the id's

Consider the consuming client and what they're going to do next. If you strip the answers from objects to just id's, we can imagine that in many circumstances, they will have to query for the object given an id, or if you don't want to hand out the object themselves, then query the object's attributes given the id. It should cost little-to-nothing to return objects, which are more directly usable (attributes readily available) rather than id's.

1
  • It might be worth pointing out IEnumerable<IGrouping<Harbor, Ship>> as the result of the LINQ group by operator
    – Caleth
    Commented Jan 30, 2018 at 11:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.