spymemcached get and incr methods give wholly different results - java

I use spymemcached 2.6rc1 in my Java project where I want to use the Long class as a storable object. Unfortunately, when I store e.g. new Long(0) object, the get(...) and incr(...) give the wholly different results - get gives Long object that contains 48 value and incr gives 1.
Please note that 48 represents the ASCII "0" symbol. When I try to get the value for the same key directly from memcached (e.g. by using telnet) I get the correct result - 0. Strange, the Long is good serialized class. So, probably, there is some problem with default transcoding. Can somebody clarify how to resolve this situation?

There was an issue filed for this a while back (spymemcached bug 41). Here's what Dustin Sallings, the creator of Spymemcached said about the issue:
You can't mix IntegerTranscoder and incr/decr. incr/decr require the numbers to be
encoded as strings as they are language-agnostic server-side operations.
Here's a unit test that demonstrates what you're trying to do:
public void testIncrDecrBug41() throws Exception {
final String key="incrdecrbug41";
// set to zero
client.set(key, 86400, "0");
// retrieve it to see if it worked
assertEquals("0", client.get(key));
// increment it
assertEquals(1, client.incr(key, 1));
// fetch it again to see if it worked
assertEquals("1", client.get(key));
}
Note that the reason you get 49 is because decimal 49 is the string "1".
incr and decr cause a lot of confusion for people because of the server-side
semantics. In newer version of memcached (e.g. changes I don't have applied yet in
my binary branch), incr and decr will fail on non-numeric string values. That is,
your first incr would throw an exception.
In the future please file bugs at the Spymemcached project website. It can be found at http://code.google.com/p/spymemcached. That way we can fix them sooner.

Related

Automate real time data using java

I am a new bee to Automation and Java. I am working on a problem which requires me to read the read time stock market data from the database and verify it with the same with the value seen on the UI. I am ok having approximations up to 5% in the value. To verify if these tests have passed its important for me to assert the values with the value in the UI.
I have a small logic to verify these values, I wanted to know if this is a good way of coding on java or do i have a better way to achieve these results.
Alorigthm.
I read the int/float value from db.
Calculate 5% of the value in step 1.
Get the value in the UI and assert if its greater then or equal to value in step 2.
If greater i say Asseert.assertEquals(true,true) else i fail my assert.
If any better way to work for these values, request a better answer.
It's more usual to have your Assertion represent the meaning of your test, having to assert(true, true) does not do this. So:
3. Calculate the absoluete difference between the value obtained in step 1 and the UI value (when I say absolute value, you need to remember that the UI might be higher or lower than the db value, you need to make the difference to be always positive)
4. Assert.assertThat( difference < theFivePercentValue)
Also you could consider using the Hamcrest extension to JUnit that includes a closeTo() method.

How does WEKA normalize attributes?

Suppose I input to WEKA some dataset and set a normalization filter for the attributes so the values be between 0 and 1. Then suppose the normalization is done by dividing on the maximum value, and then the model is built. Then what happens if I deploy the model and in the new instances to be classified an instance has a feature value that is larger than the maximum in the training set. How such a situation is handled? Does it just take 1 or does it then take more than 1? Or does it throw an exception?
The documentation doesn't specify this for filters in general.So it must depend on the filter. I looked at the source code of weka.filters.unsupervised.attribute.Normalize which I assume you are using, and I don't see any bounds checking in it.
The actual scaling code is in the Normalize.convertInstance() method:
value = (vals[j] - m_MinArray[j]) / (m_MaxArray[j] - m_MinArray[j])
* m_Scale + m_Translation;
Barring any (unlikely) additional checks outside this method I'd say that it will scale to a value greater than 1 in the situation that you describe. To be 100% sure your best bet is to write a testcase, invoke the filter yourself, and find out. With libraries that haven't specified their working in the Javadoc, you never know what the next release will do. So if you greatly depend on a particular behaviour, it's not a bad idea to write an automated test that regression-tests the behaviour of the library.
I have the same questions as you said. I did as follows and may this method can help you:
I suppose you use the weka.filters.unsupervised.attribute.Normalize to normalize your data.
as Erwin Bolwidt said, weka use
value = (vals[j] - m_MinArray[j]) / (m_MaxArray[j] - m_MinArray[j])
* m_Scale + m_Translation;
to normalize your attribute.
Don't forget that the Normalize class has this two method:
public double[] getMinArray()
public double[] getMaxArray()
Which Returns the calculated minimum/maximum values for the attributes in the data.
And you can store the minimum/maximum values. And then use the formula to normalize your data by yourself.
Remember you can set the attribute in Instance class, and you can classify your result by Evaluation.evaluationForSingleInstance
I 'll give you the link later, may this help you.
Thank you

How to generate incremental identifier in java

I have requirement in which I continuously receive messages that needs to be written in a file. Every time a new message is received it needs to be written in a separate file. What I want is to generate an unique identifier to be used as a file-name. I also want to preserve the order of the messages as well. By this I mean, the identifier generated as a file-name should always be incremental.
I was using UUID.randomUUID() to generate file-names but the problem with this approach is that UUID only assures randomness of the identifier but is not incremental. As a result I am losing the ordering of the file (I want file generated first should appear first in the list).
Approaches known
Can use System.currentTimeMillis() but I can receive multiple messages at same time stamp.
2.Another approach could be to implement static long value and increment it whenever a file is to be created and use the long value as a file-name. But I am not sure about this approach. Also it doesn't seem to be a proper solution to my problem. I think there could be far better solutions than this one.
If someone could suggest me a better solution to this problem, will be highly appreciated.
If you want your id value to uniformly rise even between server restarts, then you must either base it on the system time or have some elaborately robust logic that persists the last ID used. Note that achieving robustness on its own is not hard, but achieving it in a performant and scalable way is.
If you additionally need the id to be unique across multiple nodes in a redundant server cluster, then you need even more elaborate logic, which definitely involves a persistent store to which all the boxes synchronize access. Making this performant is, of course, even harder.
The best option I can see is to have a quite long ID so there's room for these parts:
System.currentTimeMillis for long-term uniqueness (across restarts);
System.nanotime for finer granularity;
a unique id of each server node (determined in a platform-specific way).
The method will still have to remember the last value generated and retry in case of a duplicate. It won't have to retry too many times, though, just until the next nanoTime clock tickā€”it could even busy-wait for it.
Sketch of code without point 3 (single-node implementation):
private static long lastNanos;
public static synchronized String uniqueId() {
for (;/*ever*/;) {
final long n = System.nanoTime();
if (n == lastNanos) continue;
lastNanos = n;
return "" + System.currentTimeMillis() + n;
}
}
Ok, my hands up. My last answer was fairly flaky and I've deleted it.
Keeping with the spirit of the site, I thought I'd try a different tac.
If you say you are keeping these messages in a single file then you could try something like creating an unique Id out of the size of the file?
Before you write the message to the file it's id could be the current size of the file.
You could add the filename + size as the id if these messages need to be unique across a number of files.
I'll leave the hot potato of synchronization to another day. But you could wrap all of this up in a syncronized object that keeps track of things.
Also, I am assuming that any messages written to the file will not be removed in the future.
ADDITIONAL NOTE:
You could create an message processing object that opens the file on construction (or via a create method).
This object will get the initial size of the file and this will be used as the unique id.
As each message is added (in a synchronized manner), the id is incremented by the size of the message.
This would address the performance issues. Will not work if more than one JVM/Node accesses the same file.
Skeletal Idea:
public class MessageSink {
private long id = 0;
public MessageSink(String filename) {
id = ... get file size ..
}
public synchronized addMessage(Message msg) {
msg.setId(id);
.. write to file + flush ..
.. or add to stack of messages that need to be written to file
.. at a later stage.
id = id + msg.getSize();
}
public void flushMessages() {
.. open file
.. for each message in stack write ...
.. flush and close file
}
}
I had the same requirement and found a suitable solution. Twitter Snowflake uses a simple algorithm to generate sortable 64bit (long) ids. Snowflake is written on Scala but the approach is simple and could be easily used in a Java code.
id is composed of:
timestamp - 41 bits (millisecond precision w/ a custom epoch gives us 69 years);
machine id - 10 bits (MAC address could be used as a hardware id);
sequence number - 12 bits - rolls over every 4096 per machine (with protection to avoid rollover in the same ms)
Formula looks like: ((timestamp - customEpoch) << timestampShift) | (machineId << machineIdShift) | sequenceNumber;
Shift for each component depends on it's bits position in ID.
Detailed description and source code could be found at github:
Twitter Snowflake
Basic Java implementation of the Snowflake algorithm

Mongodb java api: WriteResult#getN()

I'm writing some Java code using MongoDB with Java API and I'm unsure of some part of the Javadoc.
In a multi-thread context I use DBCollection.html#update(com.mongodb.DBObject, com.mongodb.DBObject) to update a unique document, but I saw that two threads could try to write concurrently. In this context, I observed that only one write was done, as Mongodb seems to use optimistic write lock, but I wanted to find out programmatically in which thread the write was the one who wrote, and which one was not. As a "no update" behavior was silent (I mean no exception or something), I searched into the API some way to answer my issue and after some tests found out this method: WriteResult#getN()
public int getN()
Gets the "n" field
Returns:
The description is, hum... not really exhaustive. My tests showed that the thread that win the write has a getN() that return 1, and the other 0.
So my question is: Could someone confirm this ?
From the GetLastError() documentation
The return value from the command is an object with various fields. The common fields are listed below; there may also be other fields.
ok - true indicates the getLastError command completed successfully. This does NOT indicate there wasn't a last error.
err - if non-null, indicates an error occurred. Value is a textual description of the error.
code - if set, indicates the error code which occurred. connectionId - the id of the connection
lastOp - the op-id from the last operation
For updates:
n - if an update was done, this is the number of documents updated.
So in this context, 'get "n" field' means get n which is the number of documents updated. Without "multi" being set to true it can only be either 0 or 1.

Java string to double conversion

I've been reading up on the net about the issues with handling float and double types in java. Unfortunately, the image is still not clear. Hence, i'm asking here direct. :(
My MySQL table has various DECIMAL(m,d) columns. The m may range from 5 to 30. d stays a constant at 2.
Question 1.
What equivalent data-type should i be using in Java to work (i.e store, retrieve, and process) with the size of the values in my table? (I've settled with double - hence this post).
Question 2.
While trying to parse a double from a string, i'm getting errors
Double dpu = new Double(dpuField.getText());
for example -
"1" -> java.lang.NumberFormatException: empty String
"10" -> 1.0
"101" -> 10.0
"101." -> 101.0
"101.1" -> 101.0
"101.19" -> 101.1
What am i doing wrong? What is the correct way to convert a string to a double value?
And what measures should i take to perform operations on such values?
EDIT
This is the code -
System.out.println(dpuField.getText());
Double dpu = new Double(dpuField.getText());
System.out.println(dpu);
Yes, the problem lies with getText() reporting the wrong value of the dpuField.
This method is called on the JTextField keyTyped event. So what's going wrong here?
EDIT 2
Looking at :
http://journals.ecs.soton.ac.uk/java/tutorial/post1.0/ui/keylistener.html
Apparently, keyTyped() does not give me the keycode. I'll have to switch to keyRealeased()
What equivalent data-type should i be using in Java to work (i.e store, retrieve, and process) with the size of the values in my table? (I've settled with double - hence this post).
Since it's a DECIMAL field, you should prefer java.math.BigDecimal. You can store it in DB using PreparedStatement#setBigDecimal() and you can retrieve it from DB using ResultSet#getBigDecimal().
While trying to parse a double from a string, i'm getting errors
This can't be true. The problem lies somewhere else. Maybe it is just not returning the data you expect to be returned or you are not using/debugging the values you expect them to be.
if you need exact precision without rounding errors, you should use a BigDecimal.
Your code looks OK - could it be that dpuField.getText() somehow cuts the last character from the string values you list above?
Update: you say
Yes, the problem lies with getText() reporting the wrong value of the dpuField. This method is called on the JTextField keyTyped event.
Could it be that getText() returns the value of the field before the last typed key is actually appended to it?
For decimal, I believe you risk losing precision if you don't use a BigDecimal on the Java side, as some decimal fractions can't be stored as a binary fraction.
Prefer Double.valueOf(String) over the constructor, but that's a valid way. Something else must be going on (i.e. I doubt those are the actual String values you're passing in).
Question1: It's bad idea to map DECIMAL columns to Double, usually the BigDecimal is the correct type. http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/mapping.html#1055175
Question 2: You are doing something wrong; print the String value before converting.

Categories