> -----Original Message----- > From: Juozas Baliuka [mailto:[EMAIL PROTECTED]] > Sent: Thursday, January 31, 2002 12:23 PM > To: Jakarta Commons Developers List > Subject: RE: Serious problem with MRUMap -- JCS LRU and MRUMap -- RE: > [simplestore] enhancements (was: [simplestore] inital check in) > > <skip> > >You should try to build it as a memory plugin for JCS. It might require > >some element attribute additions (what type of reference) if they are > >useful. > > > >The cache hub manages expiration at request time, this could be moved to > >a background thread. Cleanup of unused items could result in spooling. > > Sorry, I can't use any "background cleanup" it has no meaning for memory > cache. Sure it does. > This thread can remove objects from cache, but not from memory, if > application has strong reference on object. Yes. It can remove it from the cache. > "expiration at request time" has no meaning if application has strong > reference on object. > It can be removed from the cache. > example situation : > ............................................... > User u = cache.get(id); > if( u == null ){ > u = User.create( id ); > cache.put(id,u); > session.setAttribute("user",u);// I have strong reference here > team.add(u); > } > .............................................. > > request.setAttribute("player",u); > > ............................................... > > Requests, operations , but I don't remove "user" from session > .............................................. > > assertTrue("try to increase sessin time out", session.isValid() ); > // my session is valid at this time. > // cache must not remove my "user" if GC not decided to do this. > > assertEquals("cache doe's not work or bug in GC ", > session.getAttribute("user"), cache.get(id)); > > Cache must release unused references, if memory is "low" and must never > remove object from cache if it used by application. > Why? Is it a cached store? It can be removed from the store. I'm not sure what you are trying to do or why. Good luck. > if this test fails I don't need this kind of cache, it can be very fast, > but not useful. > > > > > > > >JCS has a memory index of disk items. The performance is better than a > >B tree, but it takes some memory (around 1.5 Mb for 500,000 items, not > >much if you ask me.) There are also B tree disk plugins. . . . . > > > > > > > > > > I believe everything can be optimized, and thank you for help. > > > > > > At 12:23 AM 1/31/2002 -0500, you wrote: > > > > > > >I found this example of a MRUCache on the sun site and tried making a > > > >memory cache plugin with the technique. > > > > > > > > > >http://developer.java.sun.com/developer/onlineTraining/Programming/JDCB > >o > > > >ok/perf4.html > > > > > > > >The performance of the LinkedList remove function makes it unusable. > > > >They should deprecate it. > > > > > > > >I'm going to check the code into JCS as an example. I got around the > > > >remove problem for initial puts, since you can avoid a remove, but > >any > > > >updates will kill you. Since every get in this system requires an > > > >update of the linked list, it makes the technique unscalable. > > > > > > > >The simplestore MRUMap class is pretty much the same as this example, > > > >except it takes the remove hit for just about every operation, even > >an > > > >initial put. > > > > > > > >I've included some results and the main method I used to test the > >MRUMap > > > >below. Just watch the performance degrade. > > > > > > > > > > > >G:\dev\bin\classes>java MRUMap 1000 2 > > > >took 111 ms. to put 1000 > > > >took 170 ms. to get 1000 > > > >took 160 ms. to put 1000 > > > >took 150 ms. to get 1000 > > > > > > > >G:\dev\bin\classes>java MRUMap 2000 2 > > > >took 290 ms. to put 2000 > > > >took 891 ms. to get 2000 > > > >took 691 ms. to put 2000 > > > >took 711 ms. to get 2000 > > > > > > > >G:\dev\bin\classes>java MRUMap 3000 2 > > > >took 1272 ms. to put 3000 > > > >took 3365 ms. to get 3000 > > > >took 3165 ms. to put 3000 > > > >took 3645 ms. to get 3000 > > > > > > > >G:\dev\bin\classes>java MRUMap 5000 2 > > > >took 6389 ms. to put 5000 > > > >took 16665 ms. to get 5000 > > > >took 16764 ms. to put 5000 > > > >took 16885 ms. to get 5000 > > > > > > > >G:\dev\bin\classes>java MRUMap 9000 2 > > > >took 26779 ms. to put 9000 > > > >took 56403 ms. to get 9000 > > > >took 51044 ms. to put 9000 > > > >took 54429 ms. to get 9000 > > > > > > > > > > > >(Oh, I depackaged the MRUMap to make it easier to work with. I > >attached > > > >it.) > > > > > > > >The test method for MRUMap: > > > > > > > > > >/////////////////////////////////////////////////////////////////////// > >/ > > > >// > > > > > > > > public static void main( String[] args ) { > > > > > > > > int size = 1000; > > > > if ( args.length > 0 ) { > > > > try { > > > > size = Integer.parseInt(args[0]); > > > > } catch ( NumberFormatException e ) { > > > > System.out.println( "arg 1 (size) should be a > >number" ); > > > > } > > > > } > > > > > > > > int cycles = 2; > > > > if ( args.length > 1 ) { > > > > try { > > > > cycles = Integer.parseInt(args[1]); > > > > } catch ( NumberFormatException e ) { > > > > System.out.println( "arg 2 (cycles) should be a > >number" > > > >); > > > > } > > > > } > > > > > > > > MRUMap map = new MRUMap( size ); > > > > > > > > boolean show = false; > > > > if ( args.length > 2 ) { > > > > try { > > > > show = Boolean.valueOf(args[2]).booleanValue();; > > > > } catch ( Exception e ) { > > > > System.out.println( "arg 3 (show) should be true or > > > >false" ); > > > > } > > > > } > > > > > > > > for ( int i = 0; i < cycles; i++ ) { > > > > long startP = System.currentTimeMillis(); > > > > for ( int j = 0; j <= size; j++ ) { > > > > map.put( "key" + j, "value" + j ); > > > > } > > > > long endP = System.currentTimeMillis(); > > > > long deltaP = endP - startP; > > > > System.out.println( "took " + deltaP + " ms. to put " + > >size > > > >); > > > > > > > > long startG = System.currentTimeMillis(); > > > > for ( int j = 0; j <= size; j++ ) { > > > > String val = (String)map.get( "key" + j ); > > > > if ( show ) { > > > > System.out.println( val ); > > > > } > > > > } > > > > long endG = System.currentTimeMillis(); > > > > long deltaG = endG - startG; > > > > System.out.println( "took " + deltaG + " ms. to get " + > >size > > > >); > > > > > > > > } > > > > > > > > } // end main > > > > > > > > > >\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ > >\ > > > >\\\ > > > > > > > > > > > > > > > > > > > >The bad method in java.util.LinkedList > > > > > > > > > > > >///////////////////////////////////////////////////// > > > > /** > > > > * Removes the first occurrence of the specified element in this > > > >list. If > > > > * the list does not contain the element, it is unchanged. More > > > >formally, > > > > * removes the element with the lowest index <tt>i</tt> such > >that > > > > * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt> (if such > >an > > > > * element exists). > > > > * > > > > * @param o element to be removed from this list, if present. > > > > * @return <tt>true</tt> if the list contained the specified > > > >element. > > > > */ > > > > public boolean remove(Object o) { > > > > if (o==null) { > > > > for (Entry e = header.next; e != header; e = e.next) { > > > > if (e.element==null) { > > > > remove(e); > > > > return true; > > > > } > > > > } > > > > } else { > > > > for (Entry e = header.next; e != header; e = e.next) { > > > > if (o.equals(e.element)) { > > > > remove(e); > > > > return true; > > > > } > > > > } > > > > } > > > > return false; > > > > } > > > > > > > >///////////////////////////////////////// > > > > > > > > > > > >The LRUMemoryCache in JCS gets inside the linked list and doesn't > >suffer > > > >from these problems. On average, with 9000 items the cache JCS is > >over > > > >1000 time faster than the MRUMap. > > > > > > > >Here are some times from the JCS tester using only the memory cache. > > > >These tests went through the cache hub with all the added operations. > > > > > > > >putm 9000 > > > >---put 9000 in 220 millis --- > > > >enter command: > > > >putm 9000 > > > >---put 9000 in 180 millis --- > > > >enter command: > > > >putm 9000 > > > >---put 9000 in 220 millis --- > > > >enter command: > > > >putm 9000 > > > >---put 9000 in 221 millis --- > > > >enter command: > > > >getm 9000 false > > > >---got 9000 in 40 millis --- > > > >enter command: > > > >getm 9000 false > > > >---got 9000 in 60 millis --- > > > >enter command: > > > >getm 9000 false > > > >---got 9000 in 50 millis --- > > > >enter command: > > > >getm 9000 false > > > >---got 9000 in 50 millis --- > > > > > > > > > > > >[The configuration > > > >################## JCS CACHE REGIONS AVAILABLE ################### > > > ># Regions preconfirgured for caching > > > >jcs.region.testCache1=DC > > > > > >jcs.region.testCache1.cacheattributes=org.apache.stratum.jcs.engine.Com > >p > > > >ositeCacheAttributes > > > >jcs.region.testCache1.cacheattributes.MaxObjects=20000 > > > > > >jcs.region.testCache1.cacheattributes.MemoryCacheName=org.apache.stratu > >m > > > >.jcs.engine.memory.lru.LRUMemoryCache > > > >] > > > > > > > >enter command: > > > >putm 20000 > > > >---put 20000 in 761 millis --- > > > >enter command: > > > >getm 20000 false > > > >---got 20000 in 301 millis --- > > > >enter command: > > > >putm 20000 > > > >---put 20000 in 781 millis --- > > > >enter command: > > > >getm 20000 false > > > >---got 20000 in 220 millis --- > > > >enter command: > > > > > > > > > > > >Another configuration (max mem at 1000, all gets shuffling, no > >getting > > > >of first element, hence all the gets at 2000 are from disk and memory > > > >elements are being replaced) > > > > > > > >[configuration > > > ># Regions preconfirgured for caching > > > >jcs.region.testCache1=DC > > > > > >jcs.region.testCache1.cacheattributes=org.apache.stratum.jcs.engine.Com > >p > > > >ositeCacheAttributes > > > >jcs.region.testCache1.cacheattributes.MaxObjects=1000 > > > > > >jcs.region.testCache1.cacheattributes.MemoryCacheName=org.apache.stratu > >m > > > >.jcs.engine.memory.lru.LRUMemoryCache > > > >] > > > > > > > >enter command: > > > >putm 2000 > > > >---put 2000 in 621 millis --- > > > >enter command: > > > >getm 2000 false > > > >---got 2000 in 1653 millis --- > > > >enter command: > > > >getm 2000 false > > > >---got 2000 in 1102 millis --- > > > >enter command: > > > >getm 2000 false > > > >---got 2000 in 1172 millis --- > > > >enter command: > > > >getm 2000 false > > > >---got 2000 in 1241 millis --- > > > >enter command: > > > >getm 2000 false > > > >---got 2000 in 1132 millis --- > > > >enter command: > > > >putm 2000 > > > >---put 2000 in 170 millis --- > > > >enter command: > > > >putm 2000 > > > >---put 2000 in 151 millis --- > > > >enter command: > > > >putm 2000 > > > >---put 2000 in 100 millis --- > > > >enter command: > > > >putm 2000 > > > >---put 2000 in 40 millis --- > > > >enter command: > > > >getm 2000 false > > > >---got 2000 in 1202 millis --- > > > >enter command: > > > >getm 2000 false > > > >---got 2000 in 1141 millis --- > > > >enter command: > > > >getm 2000 false > > > >---got 2000 in 1242 millis --- > > > >enter command: > > > > > > > >-- > > > >To unsubscribe, e-mail: <mailto:commons-dev-> > > [EMAIL PROTECTED]> > > > >For additional commands, e-mail: <mailto:commons-dev-> > > [EMAIL PROTECTED]> > > > > > > > > > > > > -- > > > To unsubscribe, e-mail: <mailto:commons-dev-> > > [EMAIL PROTECTED]> > > > For additional commands, e-mail: <mailto:commons-dev-> > > [EMAIL PROTECTED]> > > > > > >-- > >To unsubscribe, e-mail: <mailto:commons-dev- > [EMAIL PROTECTED]> > >For additional commands, e-mail: <mailto:commons-dev- > [EMAIL PROTECTED]> > > > > -- > To unsubscribe, e-mail: <mailto:commons-dev- > [EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:commons-dev- > [EMAIL PROTECTED]>
