OptaPlanner #PlanningPin, null entities and .fromUniquePair() - optaplanner

I need some clarification, maybe someone can help me about the pinned and null entities with .from(). I understand that I need to use .fromUnfiltered() to get them in the stream. But what about .fromUniquePair(), are entities propagated down the stream if they are null and pinned ? Similar question if I use .fromUnfiltered() with a .join(), will the join() take the null and pinned entities in the second class?
Thank you!

Pinning has no effect on Constraint Streams - both from() and join() will always include pinned entities. Let's therefore concentrate on the uninitizalized entities.
The thing to understand about fromUniquePair(Something.class) is that it is a shorthand for the following:
from(Something.class)
.join(Something.class, ...) // Replace "..." with joiners to get unique pairs.
Therefore, both the left and the right will retrieve only initialized entities. If you want unique pairs including uninitialized entities, you will have to give up the shorthand and use a nested stream:
fromUnfiltered(Something.class)
.join(fromUnfiltered(Something.class), ...) // Replace "..." with the same joiners as above.

Related

Why must MutableMap.keys returns a MutableSet?

The MutableMap.keys property is defined as : abstract val keys: MutableSet<K>
I understand that the content of keys will change as the underlying map will change, but how can the keys it-self be modifiable ? IE : I see no logic in calling map.keys.add(xxx)
Rq: I came into this problem while creating a proxy around a MutableMap. I have to temper the entries and keys content, but do not want to implement the remove/add/clear methods
The MutableSet returned by keys throws UnsupportedOperationException if you try to add something. It provides remove and filtering (retainAll) operations, which can simplify actions that don't need to consider the values, only the keys.
If you're already using a MutableMap, it makes sense that you should also be able to work with the keys directly in a mutable way.
It corresponds to the Java Map#keySet() method which is documented as follows:
Returns a Set view of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in progress (except through the iterator's own remove operation), the results of the iteration are undefined. The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.
The bolded parts explain why it's represented as MutableSet in Kotlin; otherwise you couldn't port Java code using these capabilities.

Using google protobuffer for delta messages

I am looking into using Google Protobuffers for delta messaging. Meaning I only want to send out the changed values of my domain object.
But that exposes a problem with the protocol for this purpose. I can easily just omit the properties that have not changed, and that will present us with a compact message.
But what about properties that change value from _something_ to null? There is no way to distinguish between these two scenarios in a protocol buffer.
What have others done here? I am looking at a few different solutions:
Add a meta property to all objects, that is an array of int. In case any of the properties should change to null, include the field number in this array. If no properties change, then the meta property is just omitted and doesn't take up bandwidth in the message.
Add a meta property that is a bit mask, but works like the array mentioned in option 1. This might be harder for clients to understand though.
Use a standard way that I haven't been able to find yet.
BR Jay
Protobuf 3 isn't very well suited for this. But in protobuf 2, you can have a field that is present but has value of null.
Because protobuf 2 isn't going to disappear any time soon, I'd suggest just use that for this kind of purposes.
I just wanted to post a follow-up on this and explain what I did.
As #jpa correctly pointed out protobuffers are not made for delta-compression.
So the way I solved it was to use some meta properties and rely on that convention. I have a close partnership with the people consuming the data, so conventions can be agreed upon.
Values that are set specifically to null
I have added an int array to the messages. This int array is empty most of the time and does not have an impact on the message size. When a property is set to null, I will add the property tag to this array and that way indicate that it has specifically been set to null in that message update.
Arrays that are emptied
This works in the same way as the nulls array. I have added an int array to the messages. This int array is empty most of the time and does not have an impact on the message size. When an array is emptied, I will add the property tag to this array and that way indicate that it has specifically been emptied that message update.
Objects that are deleted
To indicate that an object has been deleted, I have added a boolean property indicating that the object has been deleted. When the object is deleted I will set this value to true, and otherwise null, so it doesn't take up space in the message. The resulting message is the key identifier for that object and the boolean indicating that it is deleted.
It requires that the convention is understood by the clients but otherwise it works pretty well.

RavenDb GenerateDocumentKey

I need to generate Id for child object of my document. What is the current syntax for generating document key?
session.Advanced.Conventions.GenerateDocumentKey(document) is not there anymore. I've found _documentSession.Advanced.DocumentStore.Conventions.GenerateDocumentKey method but its' signature is weird: I am okay with default key generation algorithm I just want to pass an object and receive an Id.
The default implementation of GenerateDocumentKey is to get the "dynamic tag name" for the class, and append a slash. For example, class Foo would turn into Foos/ which then goes through the HiLoKeyGenerator so that ids can be assigned on the client-side without having to consult the server each time.
If you really want this behavior, you could try to use the HiLoKeyGenerator on your own, but have you considered something simpler? I don't know what your model is, but if the child thing is fully owned by the containing document (which it should be, to be in the same document) have you have several much easier options:
Just use the index within the collection
Keep a int NextChildThingId property on the document and increment that every time you add a ChildThing
Just use a Guid, although those are no fun to read, type, look at, compare, or speak to someone over the phone.

Overextending object design by adding many trivial fields?

I have to add a bunch of trivial or seldom used attributes to an object in my business model.
So, imagine class Foo which has a bunch of standard information such as Price, Color, Weight, Length. Now, I need to add a bunch of attributes to Foo that are rarely deviating from the norm and rarely used (in the scope of the entire domain). So, Foo.DisplayWhenConditionIsX is true for 95% of instances; likewise, Foo.ShowPriceWhenConditionIsY is almost always true, and Foo.PriceWhenViewedByZ has the same value as Foo.Price most of the time.
It just smells wrong to me to add a dozen fields like this to both my class and database table. However, I don't know that wrapping these new fields into their own FooDisplayAttributes class makes sense. That feels like adding complexity to my DAL and BLL for little gain other than a smaller object. Any recommendations?
Try setting up a separate storage class/struct for the rarely used fields and hold it as a single field, say "rarelyUsedFields" (for example, it will be a pointer in C++ and a reference in Java - you don't mention your language.)
Have setters/getters for these fields on your class. Setters will check if the value is not the same as default and lazily initialize rarelyUsedFields, then set the respective field value (say, rarelyUsedFields.DisplayWhenConditionIsX = false). Getters they will read the rarelyUsedFields value and return default values (true for DisplayWhenConditionIsX and so on) if it is NULL, otherwise return rarelyUsedFields.DisplayWhenConditionIsX.
This approach is used quite often, see WebKit's Node.h as an example (and its focused() method.)
Abstraction makes your question a bit hard to understand, but I would suggest using custom getters such as Foo.getPrice() and Foo.getSpecialPrice().
The first one would simply return the attribute, while the second would perform operations on it first.
This is only possible if there is a way to calculate the "seldom used version" from the original attribute value, but in most common cases this would be possible, providing you can access data from another object storing parameters, such as FooShop.getCurrentDiscount().
The problem I see is more about the Foo object having side effects.
In your example, I see two features : display and price.
I would build one or many Displayer (who knows how to display) and make the price a component object, with a list of internal price modificators.
Note all this is relevant only if your Foo objects are called by numerous clients.

Why does Seq[V] not extend Map[Int,V] nor does Set[V] extend Map[V,Bool]?

The three immediate subtypes of Iterable are Map, Seq, and Set. It seems like—aside from performance issues—a Seq is a map from integers to values, and a Set is a map from values to booleans (true if the value is in the set, false otherwise).
If this is the case, why is this not expressed in the type system by making Seq[V] extend Map[Int, V] and Set[V] extend Map[V, Boolean]?
Well, they sort of do, at least actually common functionality. Seq[B] inherits from Int => B (via PartialFunction[Int, B]), Map[A, B] inherits from A => B (also via PartialFunction[A, B]), and Set[A] inherits from A => Boolean. Thus, as far as function application and composition methods are concerned, all three can be used interchangeably. Additionally, they can be used interchangeably as far as traversal goes, as all implement TraversableLike.
Seeing a sequence as an assignment from integers to elements is only one way to describe what a sequence is. There are other ways, and there is no reason why that way of describing a sequence should become canonical. The actual purpose of a sequence is to make a bunch of elements accessible and traversable. A sequence is not required to actually assign integer numbers to the elements. For example, most Stream implementations probably don't have a counter running in parallel to the traversal. Requiring that would impose an unnecessary overhead on the implementation.
Besides, a Map[K,V] is also an Iterable[(K,V)]. Following your suggestion, a Seq[A] would also have to be a Map[Int,A], which would by that also make it an Iterable[(Int,A)]. Since Seq extends Iterable, this would make the Seq[A] both an Iterable[A] and an Iterable[(Int,A)] (and, recursively, an Iterable[(Int,(Int,A))], Iterable[(Int,(Int,(Int,A)))], and so on), which is not an allowed way of inheritance in Scala.
You can construct a similar argument for your suggestion regarding Set.
Well, if all you care about Seq and Set was that, you'd have a point. Myself, I happen to think that's one of the least importants aspects, and one which is already well represented by all of them being functions.
That is, a Map is a function of a key into a value, a Seq is a function of an Int into a value, and a Set is a function of a value into a Boolean. This property, which you called a "map", is a funciton. And it is already shared by all three.
What, in my opinion, Map, Seq and Set are really about are:
A Seq is concerned about knowing in what order its elements are. Conceptually, how would you prepend an element in a Map? You'd have to renumber all keys!
A Set is concerned about the presence or absence of an element. How one would model that in a Map? It would have to be a map with default value -- not a common map -- and one in which all non-default values are the same! That is clearly a degenerate behavior, not an abstraction.
A Map is concerned about mapping arbitrary keys to arbitrary values. A Seq doesn't have arbitrary keys, and a Set doesn't have arbitrary values.