devbox@COMPUTEC The Computec development blog

16Apr/100

ColdFusion UDF to intersect two lists

Just a quick one: I have a method that takes a list argument; there is a discrete list of legal values for this list. I want to filter the passed argument list by throwing out all the values which are not contained in the list of legal values.

Of course I could use a nested loop to do this - but for longer lists this is neither fast nor elegant. Again I'll turn to Java for this. ColdFusion's arrays are in fact java.util.Lists, so after converting our ColdFusion lists to ColdFusion arrays, we can make use of the Java-API for lists.

Here's a quick UDF that does what I want:

<cffunction name="listIntersect" output="no" returntype="string" 
	hint="returns values from list 1 which are contained in list 2">
	<cfargument name="lstSand" type="string" required="yes" />
	<cfargument name="lstSieve" type="string" required="yes" />
	<cfargument name="chDelimiter" type="string" required="no"
		    default="," />
	<cfscript>
	var aLstSand  = listToArray(arguments.lstSand,arguments.chDelimiter);
	var aLstSieve = listToArray(arguments.lstSieve,arguments.chDelimiter);
	aLstSand.retainAll(aLstSieve);
	return arrayToList(aLstSand,arguments.chDelimiter);
	</cfscript>
</cffunction>

Usage:

<cfset lstSand   = 'foo,bar,illegalparam,whatever' />
<cfset lstSieve  = 'bar,foo,someotherval,whatever' />
<cfset lstSieved = listIntersect(lstSand,lstSieve) />
<cfoutput>#lstSieved#</cfoutput>

This will output foo,bar,whatever.

1Apr/100

Oh shut up, cfmemcached!

Over the last few months, our use of memcached has not so much grown but more like exploded. The cfmemcached project on RIAForge has been a great starter for us. The author is using spymemcached, a very useful memcached client implementation for Java.

As much as I immediately fell in love with cfmemcached as a developer, the admin in me began to be seriously annoyed by the underlying spymemcached's chattyness that was filling up my ColdFusion server log with useless babble about each and every connection it had with the memcached servers:

2010-04-01 14:28:43.569 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/192.168.222.80:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, t
oWrite=0, interested=0} to connect queue
2010-04-01 14:28:43.570 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/192.168.222.81:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, t
oWrite=0, interested=0} to connect queue
2010-04-01 14:28:43.576 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@5081e9d3
2010-04-01 14:28:43.577 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@11e44f0
2010-04-01 14:28:59.476 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/192.168.222.80:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, t
oWrite=0, interested=0} to connect queue
2010-04-01 17:02:37.723 INFO net.spy.memcached.transcoders.SerializingTranscoder:  Compressed java.lang.String from 20798 to 4387
2010-04-01 17:02:37.731 INFO net.spy.memcached.transcoders.SerializingTranscoder:  Compressed java.lang.String from 55548 to 9819
2010-04-01 17:02:41.866 INFO net.spy.memcached.transcoders.SerializingTranscoder:  Compressed java.lang.String from 391919 to 45429

etc.

After a bit of research I discovered that this beast can be configured to use Log4J and I could thus shut it up quite nicely. All that is necessary are a few additions to our jvm.config and a Log4J-properties-file.

I've got a CF multi-instance install in /opt/jrun4/. I modified the jvm.config in the bin subdirectory of my installation and added the following to the java.args-line:

-Dnet.spy.log.LoggerImpl=net.spy.memcached.compat.log.Log4JLogger -Dlog4j.configuration=file:/opt/jrun4/bin/log4j.properties

(please note that there are no linebreaks in here!)

Then I created the log4j.properties-file in /opt/jrun4/bin/. This contains just two lines so far:

log4j.rootCategory=info
log4j.category.net.spy.memcached=warn

After a restart of the instance, no more chatter. Enjoy the silence!