Markus Hoenicka writes:
 > There is quite obviously some sort of platform-dependence at
 > work. While everything seems fine on my development platform, the
 > performance on Linux is less than desired. As I haven't seen any
 > complaints about the mysql or pgsql drivers on Linux lately I assume
 > these are driver problems, not libdbi problems. I'll investigate.
 > 

Turns out this is a libdbi problem, not a driver problem. The libdbi
function _isolate_attrib() used floating-point math to isolate the
relevant bits of an integer to e.g. determine the size of an integer
field. Apparently the implementations of the log() function differ
between FreeBSD and Linux sufficiently to break this code. I've
replaced the floating point math with a simple bit shifting loop (feel
free to improve the performance) which works ok both on FreeBSD and on
Linux (and, most likely, everywhere else).

The reason why only the sqlite and sqlite3 drivers appeared to be
affected is that not all drivers use _isolate_attrib() as there are
other ways to do this. Thus only firebird, oracle, sqlite, and sqlite3
were affected by this libdbi bug.

I've checked in this libdbi fix (revision 1.96 of dbi_main.c). If
anyone needs to "fix" one of the affected drivers on Linux without
using the cvs version of libdbi, please apply the appended patch.

regards,
Markus

--- dbi_main.c  2008/11/28 22:28:51     1.95
+++ dbi_main.c  2009/05/08 23:22:33     1.96
@@ -1570,8 +1574,19 @@
        /* hahaha! who woulda ever thunk strawberry's code would come in handy? 
*/
        // find first (highest) bit set; methods not using FP can be found at 
        // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
-       unsigned startbit = log(rangemin)/log(2);
-       unsigned endbit = log(rangemax)/log(2);
+/*     unsigned startbit = log(rangemin)/log(2); */
+/*     unsigned endbit = log(rangemax)/log(2); */
+  unsigned int startbit = 0;
+  unsigned int endbit = 0;
+
+  while (rangemin >>= 1) {
+    startbit++;
+  }
+
+  while (rangemax >>= 1) {
+    endbit++;
+  }
+
        // construct mask from startbit to endbit inclusive
        unsigned attrib_mask = ((1<<(endbit+1))-1) ^ ((1<<startbit)-1);
        return attribs & attrib_mask;

-- 
Markus Hoenicka
markus.hoeni...@cats.de
(Spam-protected email: replace the quadrupeds with "mhoenicka")
http://www.mhoenicka.de

------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image 
processing features enabled. http://p.sf.net/sfu/kodak-com
_______________________________________________
Libdbi-drivers-devel mailing list
Libdbi-drivers-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libdbi-drivers-devel

Reply via email to