Why Does Spring 4's SimpleKey Object Store the Method Parameters? - spring

I'm wondering why the SimpleKeyGenerator in Spring 4+ doesn't just return an Integer representing a hash of the method parameters? Since the returned SimpleKey stores the actual method parameters, it was leading to excessive memory usage and garbage collection in my web application, bringing the whole thing down every two days or so. (Some of these parameters were fairly large collections of strings.) I've since had to revert to my own KeyGenerator implementation, which is basically a mishmash of code I've seen elsewhere.
I'm using EhCache 2.9 as my cache implementation.

From the API docs of SimpleKeyGenerator:
Unlike DefaultKeyGenerator, no collisions will occur with the keys generated by this class.
If SimpleKey would only store the hash code and not the actual parameters itself, this could not be guaranteed. A hash code is not a unique key, you can have different objects (or combinations of parameters, in this case) which have the same hash code (in fact, that's unavoidable, because there are more possible objects than possible hash codes - see pigeonhole principle).
In other words, without storing the parameters themselves, the equals() method of SimpleKey cannot be implemented correctly - it needs to call the equals() methods of all parameters and not just compare hash codes.
See also the API docs of DefaultKeyGenerator - that implementation of KeyGenerator indeed only stores hash codes and it's deprecated precisely because it's possible that collisions can occur, leading to incorrect behaviour.
If this causes an excessive memory usage problem, then configure your cache differently so that it doesn't grow too large or make sure you don't pass large objects to SimpleKeyGenerator for generating keys.

Related

cachemanager.net - How to get List of objects from redis cache based on key passed?

How do I get a List of objects from redis cache based on the key passed?
I am exploring cachemanager.net for redis cache. I have gone through the examples. But I could not find any example related to getting the List of objects based on the key passed.
var lst =cache.Get("Key_1");
It is returning only one object.
But I would like it like this. I have stored 1000 objects in cache with key name like Key_1, Key_2, Key_3..... Key_1000. I want to get list of 1000 objects if I pass Key_* as Key.
CacheManager does not provide any functionality to search keys or get many keys via wildcard. That's simply not how caches work.
As Karthikeyan pointed out, in Redis you could use the keys operator, but that's not a good solution and should only be used for debugging manually. Other cache systems don't even have something like that, therefore CacheManager also cannot provide that feature. Hope that makes sense ;)
With CacheManager, you can either store all your objects in one cache key and cache the list. That might have some limitations if you use redis because serialization might be become an issue.
Or, you store each object separately and retrieve them in a loop. The redis client will optimize certain things, also, in CacheManager, if you have 2 layers of caching, the performance will get better over time.
You can use redis hash instead. And you can use hgetall command to retrieve all the values in that hash.
http://redis.io/commands#hash
Or if you want to use a normal key Value pair you have to write a lua script to achieve it.
local keys = redis.call('keys','key_*')
return redis.call('mget',keys)
Keys is not advisable in production as it is blocking.
You can use scan command instead of keys to get all the keys matching that pattern and then follow the same procedure to achieve the same.

Can we access the objects we created in ruby using their object _ids in ruby?

How are the object IDs assigned in Ruby? Do some objects have fixed object_id? Can we access them using their object _ids?
How an object ID is “assigned” depends on the Ruby implementation and other factors like the OS bitness. For example, in CRuby nil.object_id returns 4 on 32-bit and 8 on 64-bit.
Additionally nil is a so called immediate value. true, false, fixnums (small integers) and sometimes even floats are other immediate values. They have fixed IDs for the following reasons:
they're passed by value and not by reference like the other (dynamically allocated) objects
there's only one nil, one true, one 19, etc. however there can be two different arrays
See the documentation of BasicObject#object_id. You can also click to toggle the source to get a look at the CRuby implementation.
Call ObjectSpace._id2ref to retrieve an object by ID:
id = nil.object_id
ObjectSpace._id2ref(id) # => nil
In some implementations that method may not be implemented or really slow. According to matz it was originally a hack needed to implement weakref but current versions don't call it anymore.
How are the object IDs assigned in Ruby?
The Ruby Language Specification doesn't say anything about how IDs are assigned, only that
an object has to have the same ID over its lifetime
no two objects can have the same ID at the same time
Note that this doesn't prohibit that two different objects may have the same ID at different times, i.e. it is allowed to reuse IDs.
Do some objects have fixed object_id?
The Ruby Language Specification doesn't say anything about how IDs are assigned. On some Ruby Implementations some objects may or may not have fixed IDs.
Can we access them using their object _ids?
On some implementations, there is a method called ObjectSpace::_id2ref, but this method is not guaranteed to exist on all implementations, and it may be really expensive and on some implementations must be explicitly enabled with a command line switch.

Ruby: marshal and unmarshal a variable, not an instance

OK, Ruby gurus, this is a hard one to describe in the title, so bear with me for this explanation:
I'm looking to pass a string that represents a variable: not an instance, not the collection of properties that make up an object, but the actual variable: the handle to the object.
The reason for this is that I am dealing with resources that can be located on the filesystem, on the network, or in-memory. I want to create URI handler that can handle each of these in a consistent manner, so I can have schemes like eg.
file://
http://
ftp://
inmemory://
you get the idea. It's the last one that I'm trying to figure out: is there some way to get a string representation of a reference to an object in Ruby, and then use that string to create a new reference? I'm truly interested in marshalling the reference, not the object. Ideally there would be something like taking Object#object_id, which is easy enough to get, and using it to create a new variable elsewhere that refers to the same object. I'm aware that this could be really fragile and so is an unusual use case: it only works within one Ruby process for as long as there is an existing variable to keep the object from being garbage collected, but those are both true for the inmemory scheme I'm developing.
The only alternatives I can think of are:
marshal the whole object and cram it into the URI, but that won't work because the data in the object is an image buffer - very large
Create a global or singleton purgatory area to store a variable for retrieval later using e.g. a hash of object_id:variable pairs. This is a bit smelly, but would work.
Any other thoughts, StackOverflowers?
There's ObjectSpace._id2ref :
f = Foo.new #=> #<Foo:0x10036c9b8>
f.object_id #=> 2149278940
ObjectSpace._id2ref(2149278940) #=> #<Foo:0x10036c9b8>
In addition to the caveats about garbage collection ObjectSpace carries a large performance penalty in jruby (so much so that it's disabled by default)
Variables aren't objects in Ruby. You not only cannot marshal/unmarshal them, you can't do anything with them. You can only do something with objects, which variables aren't.
(It would be really nice if they were objects, though!)
You could look into MagLev which is an alternative Ruby implementation built on top of VMware's Gemstone. It has a distributes object model wiht might suit your use-case.
Objects are saved in the central Gemstne instance (with some nifty caching) and can be accessed by any number of remote worker instances. That way, any of the workers act on the same object space and can access the very same objects simultaneously. That way, you can even do things like having the global Garbage Collector running on a single Ruby instance or seamlessly moving execution at any point to different nodes (while preserving all the stack frames) using Continuations.

Is there any data typing for the parameters in HTTP POST?

I am building a RESTful api using a Ruby server and a MongoDB database. The database stores objects as they are, preserving their natural data types (at least those that it supports).
At the moment I am using HTTP GET to pass params to the API, and understandably everything in my database gets stored as strings (because thats what the ruby code sees when it accesses the params[] hash). After deployment, the API will use exclusively HTTP POST, so my question is whether its possible to specify the data types that get sent via POST individually for each parameter (say I have a "uid" which is an integer and a "name" which is a string), or do I need to cast them within Ruby before passing them onto my database?
If I need to cast them, are there any issues related to it?
No, its not possible.
Post variables are just string key value pairs.
You could however implement your own higher level logic.
For example a common practice is to put a suffix to the names. For example everything that ends with _i gets parsed as integer and so on.
However what benefit would it bring to preserve the types? Or better asked. How do you output them? Is it only for storage?
Then it should not be a problem to convert the strings to proper types if that benefits your application and cast them back to strings before delivering.

How to find a string in an NSArray?

This feels like such a stupid question, but how can I find a string in an NSArray?
I tried using
[array indexOfObjectIdenticalTo:myString]
but that requires the sting to have the same address.
Does anyone have any tips on how to do this?
You want the indexOfObject: method, which looks for the object by sending each object in the array an isEqual: message.
Peter's answer is correct.
One additional note; if you have tons and tons of strings in the array, -indexOfObject: is going to do a linear search. This may prove to be a performance bottleneck for which you should consider using a different container; an NSSet or NSDictionary, possibly (depending on what the strings mean).
Another gotcha is if the strings are all relatively similar and/or relatively long.
Of course, don't bother optimizing anything until you have used the analysis tools to prove that you have a performance issue.
You can use NSOrderSet as the container, the over view in NSOrderedSet Class Reference is below:
NSOrderedSet and its subclass, NSMutableOrderedSet, declare the programmatic interfaces to an ordered collection of objects.
NSOrderedSet declares the programmatic interface for static sets of distinct objects. You >establish a static set’s entries when it’s created, and thereafter the entries can’t be >modified. NSMutableOrderedSet, on the other hand, declares a programmatic interface for >dynamic sets of distinct objects. A dynamic—or mutable—set allows the addition and deletion >of entries at any time, automatically allocating memory as needed.
You can use ordered sets as an alternative to arrays when the order of elements is important >and performance in testing whether an object is contained in the set is a consideration— >testing for membership of an array is slower than testing for membership of a set.
Visit http://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSOrderedSet_Class/Reference/Reference.html
containsObject:
Returns a Boolean value that indicates whether a given object is present in the array.
(BOOL)containsObject:(id)anObject
Parameters
anObject
An object.
Return Value
YES if anObject is present in the array, otherwise NO.
Discussion
This method determines whether anObject is present in the array by sending an isEqual: message to each of the array’s objects (and passing anObject as the parameter to each isEqual: message).
Declared In
NSArray.h

Resources