Req #66794 [Opn]: dba_fetch() cdb handler implements $skip inefficiently

From: Date: Fri, 28 Feb 2014 05:02:31 +0000
Subject: Req #66794 [Opn]: dba_fetch() cdb handler implements $skip inefficiently
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-184466@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=66794&edit=1

 ID:                 66794
 User updated by:    doug at opendns dot com
 Reported by:        doug at opendns dot com
-Summary:            dba_fetch() skip parameter is inefficient when
                     accessing cdbs
+Summary:            dba_fetch() cdb handler implements $skip
                     inefficiently
 Status:             Open
 Type:               Feature/Change Request
 Package:            DBM/DBA related
 Operating System:   Any
 PHP Version:        Irrelevant
 Block user comment: N
 Private report:     N

 New Comment:

Clarified bug title


Previous Comments:
------------------------------------------------------------------------
[2014-02-28 04:58:35] doug at opendns dot com

Description:
------------
---
From manual page: http://www.php.net/function.dba-fetch
---

This is in reference to this bit of the source, which dates back to 2002, so it's applicable to
pretty much any version of php since 4.3: 

https://github.com/php/php-src/blob/master/ext/dba/dba_cdb.c#L160

When you pass a value for $skip to dba_fetch() when reading a cdb database, it'll do $skip
reads to bypass those entries. Since a common use case is to do this in a  loop (see script below)
to read an indeterminate number of duplicate keys from a database, If there end up being 100
entries, you're actually doing several thousand disk operations.

Test script:
---------------
<?php
// Write a sample cdb to demo on
$values = array_fill(0, 100, 'test value');
$cdb = dba_open('test.cdb', 'n', 'cdb');
foreach($values as $value) dba_insert('test key', $value, $cdb);
dba_close($cdb);

// Now actually show the issue (see attached dtruss link for what's happening)
$cdb = dba_open('test.cdb', 'r', 'cdb');
$cdbSkip = 0;
while ($result = dba_fetch('test key', $cdbSkip, $cdb)) {
  $cdbSkip++;
}


Expected result:
----------------
I'd expect approximately 100 read requests against the cdb from the latter half of the script

Actual result:
--------------
See this output from dtruss: https://gist.github.com/tabacco/86bd9f4b1fd267a62be2

Note the high number of seek and read operations to fetch 100 rows.


------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=66794&edit=1


Thread (3 messages)

« previous php.bugs (#184466) next »