WvStreams
wvstringcache.cc
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 2005 Net Integration Technologies, Inc.
00004  *
00005  * Definition for the WvStringCache class.  See wvstringcache.h.
00006  */
00007 #include "wvstringcache.h"
00008 #include "wvstringlist.h"
00009 
00010 WvStringTable *WvStringCache::t;
00011 int WvStringCache::refcount;
00012 size_t WvStringCache::clean_threshold;
00013 
00014 WvStringCache::WvStringCache()
00015 {
00016     refcount++;
00017     if (!t)
00018     {
00019         t = new WvStringTable;
00020         clean_threshold = 0;
00021     }
00022 }
00023 
00024 
00025 WvStringCache::~WvStringCache()
00026 {
00027     refcount--;
00028     if (!refcount)
00029     {
00030         delete t;
00031         t = NULL;
00032         clean_threshold = 0;
00033     }
00034     else
00035         clean();
00036 }
00037     
00038 
00039 WvString WvStringCache::get(WvStringParm s)
00040 {
00041     // return s; // disable cache
00042     WvString *ret = (*t)[s];
00043     if (ret)
00044     {
00045         // printf("found(%s)\n", s.cstr());
00046         return *ret;
00047     }
00048     else
00049     {
00050         // printf("  new(%s)\n", s.cstr());
00051         ret = new WvString(s);
00052         t->add(ret, true);
00053         return *ret;
00054     }
00055 }
00056 
00057 
00058 void WvStringCache::clean()
00059 {
00060     // do we actually need to clean yet?  Skip it if we haven't added too
00061     // many items since the last clean, since cleaning is pretty slow.
00062     if (t->count() < clean_threshold)
00063         return;
00064     
00065     WvStringList l;
00066     
00067     // use a two-stage process so the iterator doesn't get messed up
00068     // FIXME: this might actually be unnecessary with WvScatterHash, but
00069     // someone should actually confirm that before taking this out.
00070     {
00071         WvStringTable::Iter i(*t);
00072         for (i.rewind(); i.next(); )
00073         {
00074             if (i->is_unique()) // last remaining instance
00075             {
00076                 // printf("CLEANUP(%s)\n", i->cstr());
00077                 l.append(i.ptr(), false);
00078             }
00079         }
00080     }
00081     
00082 //    printf("CLEANUP-1: %d elements at start (%d to remove)\n",
00083 //         (int)t->count(), (int)l.count());
00084     
00085     {
00086         WvStringList::Iter i(l);
00087         for (i.rewind(); i.next(); )
00088             t->remove(i.ptr());
00089     }
00090     
00091     clean_threshold = t->count() + t->count()/10 + 1;
00092     
00093 //    printf("CLEANUP-2: %d elements left (thres=%d).\n", 
00094 //         (int)t->count(), (int)clean_threshold);
00095 }
00096 
00097