Robin Dunn wrote:
Ilia Kats wrote:
Robin Dunn wrote:
Werner F. Bruhin wrote:
Got this basically to work, however performance is not what I would like
it to be. So, I would like to make use of the cache stuff, but frankly
this is way over my head and I could not find much in the documentation
(except what is in wxListEvent), nor on the Wiki pages. No problem
setting up the EVT_LIST_CACHE_HINT, but then how do I determine to call
GetCacheFrom or GetCacheTo?
Those are methods of the wxListEvent object passed to your
EVT_LIST_CACHE_HINT handler, so when it is called you can get the
cachefrom and cachetto at that time and do whatever you need to cache
those records.
I have experiencing the same problem (I have about 15,000 rows). Robin, can
you provide us a small example that demonstrates the usage of
event.GetCacheFrom() and event.GetCacheTo() methods please?
EVT_LIST_CACHE_HINT(self, -1, self.OnCacheHint)
def OnCacheHint(self, evt):
cacheFrom = evt.GetCacheFrom()
cacheTo = evt.GetCacheTo()
# At this point you would normally do whatever is needed to
# put the data for the items from cacheFrom to cacheTo into a
# local cache of some sort, perhaps just a dictionary, but if
# your dataset is huge then you will want to use something
# that has an upper bound on the number of items and removes
# the least recently used items from the cache. Then in the
# OnGetItem* methods you would just need to retrieve the data
# from the cache object.
Anybody have any suggestions or samples for a class to use for the cache data structure? If so it would be nice to have it in the library.
Robin,
Your hint was enough to get me going, and I got it mostly working. Also I still get super flues calls to EVT_LIST_CACHE_HINT where I get the same values (or similar) for From and To as on the previous event.
Below is what I came up with, any suggestions on making this nicer, better are very welcome.
Note, that I am using ORM (Object Relational Membrane) for data access.
The one thing which is not yet working 100% is that OnGetItemText is once called BEFORE the cache event, would like to call OnCacheHint if the attribute cepageData does not exist - any hint on how I do this? Actually just noted that it is always called after the first OnGetItemText for a new range of items, which makes things somehow more complicated - but maybe someone else on the list has some good ideas on how to get around this.
Following the relevant code, again I am open for suggestions on how to improve this (even code style suggestions etc).
See you
Werner
initData - create a dictionary (cepageDataCache) with minimal data
getData - get whatever data I need for the listctrl columns and put it in a small dictionary
onCacheHint - initialize the small (cepageData) dictionary and use getData to fill it
def initData(self, ds):
"""ds = ORM datasource
Using ORM's execute so I can get just the two columns in question and
fetchall to get a list back"""
mycur = ds.execute('SELECT SYNONYMID, NAME FROM CEPAGE_SYN ORDER BY NAME')
self.cepageDataCache = mycur.fetchall()
self.SetItemCount(mycur.rowcount)
def getData(self, item, pkey):
"""item = list item number
pkey = primary key for item number
"""
where = 'synonymid=%i' % pkey[0]
row = self.ds.selectByClauses(beans.cepage_syn,
where=where).fetchone()
self.cepageData[item] = (row.name, row.cepage.name)
def OnCacheHint(self, event):
cacheFrom = event.GetCacheFrom()
cacheTo = event.GetCacheTo()
print "cacheFrom: %s, cacheTo: %s" % (cacheFrom, cacheTo)
self.cepageData = {}
item = cacheFrom
while cacheTo >= item:
self.getData(item, self.cepageDataCache[item])
item = item +1
def OnGetItemText(self, item, col):
print 'item = %s, col = %s' % (item, col)
if col == 0:
if not hasattr(self, 'cepageData'):
* # how can I call here -> self.OnCacheHint what do I need to feed it?*
dummy = ''
if self.cepageData.has_key(item):
self.colinfo = self.cepageData[item]
return self.colinfo[0]
if col == 1:
return self.colinfo[1]
Print output:
item = 597, col = 0 -> from OnGetItemText
cacheFrom: 581, cacheTo: 601
item = 583, col = 0
.... (many calls which I will send my thanks to Bill G. 
item = 594, col = 0
cacheFrom: 581, cacheTo: 601 -> why do get this one?
item = 594, col = 0
cacheFrom: 594, cacheTo: 595 -> why do get this one?
item = 594, col = 0
...
item = 594, col = 0
item = 16157, col = 0 -> why this one BEFORE the cacheHint event?
cacheFrom: 16138, cacheTo: 16157
item = 16140, col = 0
...
item = 16157, col = 0
cacheFrom: 16138, cacheTo: 16157 -> again unneeded
item = 16157, col = 0
item = 16157, col = 1
item = 16151, col = 0
cacheFrom: 16138, cacheTo: 16157 -> again unneeded
item = 16157, col = 0
item = 16157, col = 1
item = 16151, col = 0
cacheFrom: 16143, cacheTo: 16154 -> again unneeded
item = 16143, col = 0
...
item = 16157, col = 0
item = 0, col = 0 -> again before the cacheHint
cacheFrom: 0, cacheTo: 18
item = 0, col = 0