I don't really like my "solution" though -- It only works if you don't use any interesting Unicode characters.
Indeed. Any line with a character that isn't in SAFE_ASCII_RE slows down
the application a little more, at such a point that 0.9.7.2 might be
slower than 0.9.7.1.
Whereas in my tests, the solution with a cache is as good as the
SAFE_ASCII_RE one and doesn't have this drawback.
So at the beginning, I didn't like [48] and preferred Haypo's solutions.

Now I don't know what to think, because I did my tests with Hachoir only.
It's not surprising that the cache solution always works well but it may
not be the case with other applications.
Hard to say, but I doubt a cache would fail as much as SAFE_ASCII_RE.

Haypo suggested 2 cache implementations.
The first is so simple that it has a memory leak.
And the second uses deque that appeared in Python 2.4.
I've attached a third one that remains simple, without those problems.

Even if this cache isn't a less awful hack that SAFE_ASCII_RE, I hope
you will consider it.
Haypo's urwid-unicode-v7.patch [1] (yes, it conflicts with [48]) is
certainly a smarter approach.

JM

[1] http://lists.excess.org/pipermail/urwid/2006-December/000387.html


--- util-0.9.7.1.py	2007-01-14 19:18:47.774885087 +0100
+++ util.py	2007-01-14 19:20:50.401177677 +0100
@@ -554,7 +554,7 @@
 	return l
 
 
-def calc_width( text, start_offs, end_offs ):
+def _calc_width( text, start_offs, end_offs ):
 	"""
 	Return the screen column width of text between start_offs and end_offs.
 	"""
@@ -577,8 +577,26 @@
 	assert type(text) == type(""), `text`
 	# "wide" and "narrow"
 	return end_offs - start_offs
-	
-			
+
+def calc_width( *args ):
+	key = hash(args)
+	cache = calc_width.cache
+	width = cache[0].get(key)
+	if width is None:
+		if cache[1] >> 12:
+			thres = cache[1] >> 1
+			for k, v in cache[0].items():
+				v[1] -= thres
+				if v[1] < 0:
+					del cache[0][k]
+			cache[1] -= thres
+		cache[0][key] = width = [ _calc_width(*args), 0 ]
+	width[1] = cache[1]
+	cache[1] += 1
+	return width[0]
+calc_width.cache = [ {}, 0 ]
+
+
 def calc_text_pos( text, start_offs, end_offs, pref_col ):
 	"""
 	Calculate the closest position to the screen column pref_col in text


_______________________________________________
Urwid mailing list
[email protected]
http://lists.excess.org/mailman/listinfo/urwid

Reply via email to