Hazelcast Jet IMap remove entry - hazelcast-imap

I've read the documentation of Hazelcast Jet.
I've seen it is possible to add/update entries in an IMap sink.
But I've seen nowhere how it is possible to remove entries from the IMap.
Is there a way for this ?

See Sinks.mapWithMerging, from JavaDoc :
/**
* Returns a sink that uses the supplied functions to extract the key
* and value with which to update a Hazelcast {#code IMap}. If the map
* already contains the key, it applies the given {#code mergeFn} to
* resolve the existing and the proposed value into the value to use. If
* the value comes out as {#code null}, it removes the key from the map.
* Expressed as code, the sink performs the equivalent of the following for
* each item:
* <pre>
* K key = toKeyFn.apply(item);
* V oldValue = map.get(key);
* V newValue = toValueFn.apply(item);
* V resolved = (oldValue == null)
* ? newValue
: mergeFn.apply(oldValue, newValue);
* if (value == null)
* map.remove(key);
* else
* map.put(key, value);
* </pre>
...

Related

Groovy Map.get(key, default) mutates the map

I have following Groovy script:
mymap = ['key': 'value']
println mymap
v = mymap.get('notexistkey', 'default')
println v
println mymap
When I run it I get following console output:
[key:value]
default
[key:value, notexistkey:default]
I'm surprised that after calling mymap.get('notexistkey', 'default') where second parameter is a default value returned when given key does not exist, the key notexistkey is added to the map I've called the method on. Why? Is that expected behaviour? How can I prevent this mutation?
Use Java's Map.getOrDefault(key, value) instead:
mymap = ['key': 'value']
println mymap
v = mymap.getOrDefault('notexistingkey', 'default')
println v
println mymap
Output:
[key:value]
default
[key:value]
Groovy SDK adds Map.get(key, default) via DefaultGroovyMethods.get(map, key, default) and if you take a look what Javadoc says you will understand that this behaviour is expected:
Looks up an item in a Map for the given key and returns the value - unless there is no entry for the given key in which case add the default value to the map and return that.
And this is what implementation of this method looks like:
/**
* Looks up an item in a Map for the given key and returns the value - unless
* there is no entry for the given key in which case add the default value
* to the map and return that.
* <pre class="groovyTestCase">def map=[:]
* map.get("a", []) << 5
* assert map == [a:[5]]</pre>
*
* #param map a Map
* #param key the key to lookup the value of
* #param defaultValue the value to return and add to the map for this key if
* there is no entry for the given key
* #return the value of the given key or the default value, added to the map if the
* key did not exist
* #since 1.0
*/
public static <K, V> V get(Map<K, V> map, K key, V defaultValue) {
if (!map.containsKey(key)) {
map.put(key, defaultValue);
}
return map.get(key);
}
it's pretty old concept (since Groovy 1.0). However I would recommend not using it - this .get(key, default) operation is neither atomic, nor synchronized. And problems start when you use it on ConcurrentMap which is designed for concurrent access - this method breaks its contract, because there is no synchronization between containsKey, put and final get call.

Multiple function signatures in externs rule

I am writing closure externs for WebAssembly.
For function WebAssembly.instantiate, it has 2 function signatures.
Promise<{module:WebAssembly.Module, instance:WebAssembly.Instance}>
instantiate(BufferSource bytes [, importObject])
Promise<WebAssembly.Instance> instantiate(moduleObject [, importObject])
How to declare both rules in closure externs?
Reference:
https://github.com/WebAssembly/design/blob/master/JS.md#webassemblyinstantiate
You can specify that argument and result are union of two different types. See https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler about how to specify types.
Here is a simple example of such a function:
/**
* #param {string|number} value
* #return {string|number}
*/
ambiguous = function(value) {
if (typeof value == 'string') {
return value+' is string';
} else if (typeof value == 'number') {
return value+1;
} else throw new Error();
};
For your WebAssembly.instantiate function you will of course have more complex types than string and number. I don't know how you would specify the Promise types, I don't recognize the syntax shown for those, and I doubt closure compiler will parse that as-is. The extern then looks something like this (with bogus types for the Promises).
/**
#param (!BufferSource|!WebAssembly.Module) arg1 either a BufferSource or a module
#param Object= importObject optional object to import
#return (!PromiseType1|!PromiseType2)
*/
WebAssembly.instantiate = function(arg1, importObject) {};
The ! symbol is used to indicate a non-null object. If these can be null then leave that out. The = symbol after Object= means it can be undefined.
When using the results of this function you will need to test what type of thing you got using instanceof or some other method. Otherwise the compiler only knows the result is one of the two possible types. If not using instanceof, you can use type casting to tell the compiler that you know what the type is, see end of that page referenced above.
An example of a function from closure-library that has a union type in both its argument and its result is goog.array.find. The source for goog.array.find is available. Note that the angle brackets <> are used for the template type feature of the compiler.

How HashMap works internally

HashMap objHashMap = new HashMap();
objHashMap.put("key1", "Value1");
objHashMap.put("key1", "Value2");
System.out.println(objHashMap.get("key1"));
Above code displaying "Value2" how and why
check this
/**
* Associates the specified value with the specified key in this map. If the
* map previously contained a mapping for the key, the old value is
* replaced.
*
* #param key
* key with which the specified value is to be associated
* #param value
* value to be associated with the specified key
* #return the previous value associated with <tt>key</tt>, or <tt>null</tt>
* if there was no mapping for <tt>key</tt>. (A <tt>null</tt> return
* can also indicate that the map previously associated
* <tt>null</tt> with <tt>key</tt>.)
*/
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K , V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
Lets note down the steps one by one:
1) First of all, key object is checked for null. If key is null, value is stored in table[0] position. Because hash code for null is always 0.
2) Then on next step, a hash value is calculated using key’s hash code by calling its hashCode() method. This hash value is used to calculate index in array for storing Entry object. JDK designers well assumed that there might be some poorly written hashCode() functions that can return very high or low hash code value. To solve this issue, they introduced another hash() function, and passed the object’s hash code to this hash() function to bring hash value in range of array index size.
3) Now indexFor(hash, table.length) function is called to calculate exact index position for storing the Entry object.
4) Here comes the main part. Now, as we know that two unequal objects can have same hash code value, how two different objects will be stored in same array location [called bucket].
Answer is LinkedList. If you remember, Entry class had an attribute “next”. This attribute always points to next object in chain. This is exactly the behavior of LinkedList.
So, in case of collision, Entry objects are stored in LinkedList form. When an Entry object needs to be stored in particular index, HashMap checks whether there is already an entry?? If there is no entry already present, Entry object is stored in this location.
If there is already an object sitting on calculated index, its next attribute is checked. If it is null, and current Entry object becomes next node in LinkedList. If next variable is not null, procedure is followed until next is evaluated as null.
What if we add the another value object with same key as entered before. Logically, it should replace the old value. How it is done? Well, after determining the index position of Entry object, while iterating over LinkedList on calculated index, HashMap calls equals method on key object for each Entry object. All these Entry objects in LinkedList will have similar hash code but equals() method will test for true equality. If key.equals(k) will be true then both keys are treated as same key object. This will cause the replacing of value object inside Entry object only.
In this way, HashMap ensure the uniqueness of keys.
Because Hash maps store only unique keys for each value, this means that you can't put 2 keys with the same name in it, when you do you will overwrite the value for that key, so if you want to store 2 different values you need to store two different keys in it.
HashMap objHashMap = new HashMap();
objHashMap.put("key1", "Value1");
objHashMap.put("key2", "Value2"); //CHANGED THIS KEY to "key2"
System.out.println(objHashMap.get("key1"));

PHPUnit Testing Error : The system cannot find the path specified

I have installed PHPUnit via Pear.
While I try testing via PHPUnit,even after giving the test file path it shows error:
The system cannot find the path specified.
I have tried Sample code in :
https://netbeans.org/kb/docs/php/phpunit.html?print=yes#installing-phpunit
<?php
class Calculator
{
/**
* #assert (0, 0) == 0
* #assert (0, 1) == 1
* #assert (1, 0) == 1
* #assert (1, 1) == 2
* #assert (1, 2) == 4
*/
public function add($a, $b)
{
return $a + $b;
}
}
?>
Not sure what your source file is called, but there are not any tests written in for the class. You used the generator, which has created the #asserts. Now, you need to generate the test class to use those. The PHPUnit Manual Skeleton Generator is then needed to run to produce the actual tests.
With your code, you have the sample #assert annotations for what should be simple to generate test cases. Therefore, you need to generate the test cases.
phpunit-skelgen --test Calculator
or for Namespaces (where Project is the name space)
phpunit-skelgen --test -- "project\Calculator" Calculator.php
Then you can see tests generated
/**
* Generated from #assert (0, 0) == 0.
*/
public function testAdd() {
$o = new Calculator;
$this->assertEquals(0, $o->add(0, 0));
}
Finally, you can execute your tests:
phpunit --bootstrap Calculator.php --verbose CalculatorTest

Backtracking recursively with multiple solutions

function BACKTRACKING-SEARCH(csp) returns a solution, or failure
return RECURSIVE- BACKTRACKING({ }, csp)
function RECURSIVE-BACKTRACKING(assignment,csp) returns a solution, or failure
if assignment is complete then
return assignment
var ←SELECT-UNASSIGNED-VARIABLE(VARIABLES[csp],assignment,csp)
for each value in ORDER-DOMAIN-VALUES(var,assignment,csp) do
if value is consistent with assignment according to CONSTRAINTS[csp] then
add {var = value} to assignment
result ← RECURSIVE-BACKTRACKING(assignment, csp)
if result ̸= failure then
return result
remove {var = value} from assignment
return failure
This is a backtracking recursion algorythm pseudocode from AIMA. However, I don't understand if it returns ALL possible solutions or just first one found. In case it is the last option, could you please help me modify it to return a list of possible solutions instead (or at least updating some global list).
EDIT: I implemented this algorithm in Java. However, there is one problem:
if I don't return assignment, but save it in result instead, the recursion stop condition fails (i.e. it doesn't exist anymore). How can I implement another stop-condition? Maybe I should return true in the end?
Here is my code :
/**
* The actual backtracking. Unfortunately, I don't have time to implement LCV or MCV,
* therefore it will be just ordinary variable-by-variable search.
* #param line
* #param onePossibleSituation
* #param result
*/
public static boolean recursiveBacktrack(Line line, ArrayList<Integer> onePossibleSituation, ArrayList<ArrayList<Integer>> result){
if (onePossibleSituation.size() == line.getNumOfVars()){
// instead of return(assignment)
ArrayList<Integer> situationCopy = new ArrayList<Integer>();
situationCopy.addAll(onePossibleSituation);
result.add(situationCopy);
onePossibleSituation.clear();
}
Block variableToAssign = null;
// iterate through all variables and choose one unassigned
for(int i = 0; i < line.getNumOfVars(); i++){
if(!line.getCspMiniTaskVariables().get(i).isAssigned()){
variableToAssign = line.getCspMiniTaskVariables().get(i);
break;
}
}
// for each domain value for given block
for (int i = line.getCspMiniTaskDomains().get(variableToAssign.getID())[0];
i <= line.getCspMiniTaskDomains().get(variableToAssign.getID())[0]; i++){
if(!areThereConflicts(line, onePossibleSituation)){
//complete the assignment
variableToAssign.setStartPositionTemporary(i);
variableToAssign.setAssigned(true);
onePossibleSituation.add(i);
//do backtracking
boolean isPossibleToPlaceIt = recursiveBacktrack(line,onePossibleSituation,result);
if(!isPossibleToPlaceIt){
return(false);
}
}
// unassign
variableToAssign.setStartPositionTemporary(-1);
variableToAssign.setAssigned(false);
onePossibleSituation.remove(i);
}
// end of backtracking
return(false);
}
This code checks if solution found and if it is, returns the solution. Otherwise, continue backtracking. That means, it returns the first solution found.
if result ̸= failure then
return result
remove {var = value} from assignment
You can modify it like that:
if result ̸= failure then
PRINT result // do not return, just save the result
remove {var = value} from assignment
Or, better, modify this part:
if assignment is complete then
print assignment
return assignment // print it and return
About edited question:
First, return true in the first if, so recursion will know that it found a solution. The second step, there is a mistake, probably:
if(!isPossibleToPlaceIt){
return(false);
}
Should be
if(isPossibleToPlaceIt){
return(true);
}
Because if your backtracking has found something, it returns true, which means you don't have to check anything else any longer.
EDIT#2: If you want to continue backtracking to find ALL solutions, just remove the whole previous if section with return:
//if(isPossibleToPlaceIt){
// return(true);
//}
So we will continue the search in any way.

Resources