huge commit, bringing back text links, even though not completely functional if nextpage link comes _before_ the {entry} block; the commit contains the 'loose' search option for bplustree, which lets loosely search the tree for the nearest key to a given search key, which makes the thing possible; a few fixes to 404 error handling and related prettyurls stuff
This commit is contained in:
parent
4fe8540e2f
commit
e052fa4e4a
@ -978,13 +978,19 @@ class BPlusTree_Node {
|
||||
* @returns int|false corresponding integer or false if key is missing
|
||||
*
|
||||
*/
|
||||
function getvalue($key) {
|
||||
function getvalue(&$key, $loose=false) {
|
||||
|
||||
#d(implode(",",$this->keys));
|
||||
$place = array_search($key, $this->keys);
|
||||
if ($place!==false) {
|
||||
#$place = array_search($key, $this->keys);
|
||||
$place = BPT_bisect($this->keys, $key, 0);
|
||||
if (@$this->keys[$place-1] == $key) {
|
||||
return $this->indices[$place];
|
||||
} else {
|
||||
if ($loose) {
|
||||
if ($place>1) $place--;
|
||||
$key = $this->keys[$place];
|
||||
return $this->indices[$place];
|
||||
}
|
||||
trigger_error("key '$key' not found", E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
@ -1522,12 +1528,17 @@ class BPlusTree {
|
||||
/**
|
||||
* returns an iterator for the tree
|
||||
* @param string $keylower key lower limit of the iterator
|
||||
* @param bool $includelower if true $keylower is included in the iterator
|
||||
* @param bool|int $includelower if true $keylower is included in the iterator;
|
||||
* if $includelower > 1 then 'loose' search is assumed:
|
||||
* the tree will be walked starting from
|
||||
* the key $k in the tree such as $k <= $keylower
|
||||
* and such as there are NO other keys $k'
|
||||
* such as $k < $k' <= $keylower
|
||||
* @param string $keyupper key upper bound of the iterator
|
||||
* @param bool $includeupper if true $keyupper is included in the iterator
|
||||
*/
|
||||
function walker(
|
||||
$keylower =null,
|
||||
&$keylower =null,
|
||||
$includelower =null,
|
||||
$keyupper =null,
|
||||
$includeupper =null
|
||||
@ -1694,14 +1705,16 @@ class BPlusTree {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key key to find
|
||||
* @param string &$key key to find.
|
||||
* @param bool $loose if true searches the tree for the "nearest" key to $key;
|
||||
*
|
||||
* @returns int associated value
|
||||
*
|
||||
*/
|
||||
function getitem($key) {
|
||||
function getitem(&$key, $loose=false) {
|
||||
if (is_null($this->root))
|
||||
trigger_error("not open!", E_USER_ERROR);
|
||||
return $this->find($key, $this->root);
|
||||
return $this->find($key, $this->root, $loose);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1712,7 +1725,7 @@ class BPlusTree {
|
||||
* @returns int|bool value at the leaf node containing key or false if key is missing
|
||||
*
|
||||
*/
|
||||
function find($key, &$node) {
|
||||
function find(&$key, &$node, $loose=false) {
|
||||
|
||||
while (($node->flag & BPT_FLAG_INTERIOR) == BPT_FLAG_INTERIOR) {
|
||||
|
||||
@ -1736,7 +1749,7 @@ class BPlusTree {
|
||||
$node =& $node->getnode($nodekey);
|
||||
}
|
||||
|
||||
return $node->getvalue($key);
|
||||
return $node->getvalue($key, $loose);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1744,7 +1757,7 @@ class BPlusTree {
|
||||
* @returns bool false if key does not exists, true otherwise
|
||||
*/
|
||||
function has_key($key) {
|
||||
if ($this->getitem($key)!==false) {
|
||||
if (@$this->getitem($key)!==false) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -2331,7 +2344,7 @@ class BPlusWalker {
|
||||
|
||||
function BPlusWalker(
|
||||
&$tree,
|
||||
$keylower=null,
|
||||
&$keylower=null,
|
||||
$includelower=null,
|
||||
$keyupper=null,
|
||||
$includeupper=null){
|
||||
@ -2371,6 +2384,7 @@ class BPlusWalker {
|
||||
$this->node_index = null;
|
||||
$this->valid = 0;
|
||||
$this->first();
|
||||
$keylower = $this->keylower;
|
||||
}
|
||||
|
||||
function first() {
|
||||
@ -2395,7 +2409,11 @@ class BPlusWalker {
|
||||
if (!$this->valid) {
|
||||
$place = BPT_bisect($keys, $keylower, 0, $validkeys);
|
||||
if ($place < $validkeys) {
|
||||
$index = $this->node_index = $place;
|
||||
if ($place > 0)
|
||||
$index = $place - 1;
|
||||
else $index = $place;
|
||||
|
||||
$this->node_index = $index;
|
||||
$testk = $keys[$index];
|
||||
/*
|
||||
if ($testk>$keylower ||
|
||||
@ -2406,7 +2424,11 @@ class BPlusWalker {
|
||||
}
|
||||
*/
|
||||
$this->valid = BPT_keycmp($testk,$keylower)<0||#$testk>$keylower ||
|
||||
($this->includelower && $testk==$keylower);
|
||||
($this->includelower && ($this->includelower>1 || $testk==$keylower) );
|
||||
|
||||
|
||||
$this->keylower = $testk;
|
||||
|
||||
} else {
|
||||
$next =& $node->nextneighbour();
|
||||
if (!is_null($next)) {
|
||||
@ -2482,10 +2504,10 @@ class caching_BPT extends BPlusTree {
|
||||
|
||||
var $cache = array();
|
||||
|
||||
function getitem($key) {
|
||||
function getitem(&$key, $loose=false) {
|
||||
if (isset($cache[$key]))
|
||||
return $cache[$key];
|
||||
else return ($cache[$key] = parent::getitem($key));
|
||||
else return ($cache[$key] = parent::getitem($key, $loose));
|
||||
}
|
||||
|
||||
function resetcache() {
|
||||
@ -2529,9 +2551,9 @@ class SBPlusTree extends BPlusTree {
|
||||
return $seek;
|
||||
}
|
||||
|
||||
function getitem($key) {
|
||||
$seek = parent::getitem($key);
|
||||
return $this->getstring($seek);
|
||||
function getitem(&$key, $loose=false) {
|
||||
$seek = parent::getitem($key, $loose);
|
||||
return $seek!==false? $this->getstring($seek) : false;
|
||||
}
|
||||
|
||||
function setitem($key, $val) {
|
||||
@ -2541,7 +2563,7 @@ class SBPlusTree extends BPlusTree {
|
||||
}
|
||||
|
||||
function walker(
|
||||
$keylower =null,
|
||||
&$keylower =null,
|
||||
$includelower =null,
|
||||
$keyupper =null,
|
||||
$includeupper =null
|
||||
@ -2564,10 +2586,10 @@ class caching_SBPT extends SBPlusTree {
|
||||
|
||||
var $cache = array();
|
||||
|
||||
function getitem($key) {
|
||||
function getitem(&$key, $loose=false) {
|
||||
if (isset($cache[$key]))
|
||||
return $cache[$key];
|
||||
else return ($cache[$key] = parent::getitem($key));
|
||||
else return ($cache[$key] = parent::getitem($key, $loose));
|
||||
}
|
||||
|
||||
function resetcache() {
|
||||
|
@ -386,6 +386,19 @@
|
||||
return date('ymdHis', $time);
|
||||
}
|
||||
|
||||
function entry_keytotime($key) {
|
||||
$arr[ 'y' ] = substr($key, 0, 2);
|
||||
$arr[ 'm' ] = substr($key, 2, 2);
|
||||
$arr[ 'd' ] = substr($key, 4, 2);
|
||||
|
||||
$arr[ 'H' ] = substr($key, 6, 2);
|
||||
$arr[ 'M' ] = substr($key, 8, 2);
|
||||
$arr[ 'S' ] = substr($key, 10, 2);
|
||||
|
||||
return mktime($arr['H'], $arr['M'], $arr['S'],
|
||||
$arr['m'], $arr['d'], $arr['y']);
|
||||
}
|
||||
|
||||
function entry_idtotime($id) {
|
||||
$date = date_from_id($id);
|
||||
return $date['time'];
|
||||
@ -408,7 +421,7 @@
|
||||
|
||||
function entry_exists($id) {
|
||||
$f = entry_dir($id).EXT;
|
||||
return $f;file_exists($f)? $f : false;
|
||||
return file_exists($f)? $f : false;
|
||||
}
|
||||
|
||||
function entry_dir($id) {
|
||||
|
@ -45,7 +45,10 @@
|
||||
|
||||
if (entry_exists($params['id'])) {
|
||||
$this->id = $params['id'];
|
||||
|
||||
} else {
|
||||
// let it fail
|
||||
$this->count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
@ -78,7 +81,7 @@
|
||||
|
||||
}
|
||||
|
||||
if (isset($params['random'])) {
|
||||
if (isset($params['random']) && !$this->id) {
|
||||
$this->random = intval($params['random']);
|
||||
$this->count = $this->random;
|
||||
}
|
||||
@ -148,7 +151,7 @@
|
||||
$this->params =& new FPDB_QueryParams($params);
|
||||
$this->ID = $ID;
|
||||
|
||||
if ($this->params->id) {
|
||||
if ($this->params->id || $this->params->random) {
|
||||
$this->single = true;
|
||||
}
|
||||
|
||||
@ -174,13 +177,13 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->single) {
|
||||
if ($this->single || $this->params->random) {
|
||||
if ($this->params->random>0) {
|
||||
$this->_get_random_id($entry_index);
|
||||
}
|
||||
$this->_prepare_single($entry_index);
|
||||
} else {
|
||||
$this->_prepare_list($entry_index);
|
||||
if ($this->params->random>0) {
|
||||
$this->_randomize_list();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -197,34 +200,41 @@
|
||||
|
||||
$qp =& $this->params;
|
||||
|
||||
$time = entry_idtotime($qp->id);
|
||||
|
||||
// let's get a preceding key in the order relation.
|
||||
// please notice this is hardcoded to $time+1, since
|
||||
// order of the indices is not configurable by the user
|
||||
$prevkey = entry_timetokey($time+1);
|
||||
|
||||
$key = entry_idtokey($qp->id);
|
||||
#print_r($key);
|
||||
|
||||
#$key = entry_idtokey($qp->id);
|
||||
if (!($entry_index->has_key($key))){
|
||||
trigger_error("FPDB: no entry found for {$qp->id}", E_USER_WARNING);
|
||||
#trigger_error("FPDB: no entry found for {$qp->id}", E_USER_WARNING);
|
||||
$qp->count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->walker =& $entry_index->walker($key, true);
|
||||
|
||||
/*
|
||||
if ($this->counter < 0) {
|
||||
|
||||
$idlist = array_keys($entry_index);
|
||||
$fliplist = array_flip($idlist);
|
||||
|
||||
$this->local_index =& $entry_index;
|
||||
$this->local_list =& $idlist;
|
||||
|
||||
$qp->start = $fliplist[$qp->id];
|
||||
$qp->count = 1;
|
||||
// if $includelower = 2 (second parameter) then assumes 'loose' inclusion
|
||||
// i.e. includes the first key $newkey such as $newkey <= $prevkey
|
||||
// also, if $prevkey != $newkey then $prevkey := $newkey
|
||||
|
||||
|
||||
}
|
||||
|
||||
$this->pointer = $qp->start;
|
||||
*/
|
||||
$this->walker =& $entry_index->walker($prevkey, 2, null, null);
|
||||
|
||||
// since we're searching for $prevkey, i.e. a key preceding the target $id
|
||||
// in the sequence, if $prevkey becomes equal to $key then it means
|
||||
// $key is the first post (the last in time)
|
||||
|
||||
if ($prevkey == $key)
|
||||
$qp->start = 0;
|
||||
else
|
||||
$qp->start = 1;
|
||||
|
||||
$qp->start = 0;
|
||||
$qp->count = 1;
|
||||
|
||||
$this->pointer = 0;
|
||||
|
||||
}
|
||||
@ -291,34 +301,26 @@
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
function _randomize_list() {
|
||||
|
||||
// not so great implementation... doesn't work well
|
||||
function _get_random_id(&$entry_index) {
|
||||
$qp =& $this->params;
|
||||
|
||||
$i = $qp->random - 1;
|
||||
$nums = array_keys($this->local_list);
|
||||
|
||||
|
||||
if ($qp->random == 1) {
|
||||
$i = mt_rand(0, end($nums));
|
||||
$this->single = true;
|
||||
$qp->id = $this->local_list[ $i ];
|
||||
$this->_prepare_single($this->local_index);
|
||||
return;
|
||||
}
|
||||
|
||||
shuffle($nums);
|
||||
|
||||
$newlocal = array();
|
||||
do {
|
||||
$newlocal[ $i ] = $this->local_list[ $nums[$i] ];
|
||||
} while($i--);
|
||||
|
||||
$this->local_list = $newlocal;
|
||||
|
||||
if ($qp->count > $qp->random) {
|
||||
$qp->count = $qp->random;
|
||||
}
|
||||
$now = time();
|
||||
|
||||
$first = '999999999999';
|
||||
$last = '000000000000';
|
||||
$entry_index->getitem($first, true);
|
||||
$entry_index->getitem($last, true);
|
||||
|
||||
$t1 = entry_keytotime($first);
|
||||
$t2 = entry_keytotime($last);
|
||||
|
||||
$t = mt_rand($t2, $t1);
|
||||
|
||||
$random_key = entry_timetokey($t);
|
||||
$entry_index->getitem($random_key, true);
|
||||
|
||||
$qp->id = entry_keytoid($random_key);
|
||||
}
|
||||
|
||||
/* reading functions */
|
||||
@ -361,14 +363,19 @@
|
||||
$this->previd = $this->currentid;
|
||||
$id = $this->currentid = entry_keytoid($this->walker->current_key());
|
||||
|
||||
if ($this->single) $this->preventry = array('subject' => $this->walker->current_value());
|
||||
|
||||
|
||||
$this->walker->next();
|
||||
$this->pointer++;
|
||||
}
|
||||
|
||||
// pointer == start
|
||||
|
||||
$this->previd = $this->currentid;
|
||||
$prevcurr = $this->currentid;
|
||||
$id = $this->currentid = entry_keytoid($this->walker->current_key());
|
||||
if ($id != $prevcurr) $this->previd = $prevcurr;
|
||||
|
||||
|
||||
|
||||
if ($qp->fullparse && $this->counter <= 0) {
|
||||
@ -465,14 +472,16 @@
|
||||
function getNextPage() {
|
||||
|
||||
if ($this->single){
|
||||
return false;
|
||||
$id = $this->_getOffsetId(1, $this->params->start);
|
||||
#return false;
|
||||
#$id = $this->_getOffsetId(1, $this->params->start);
|
||||
$id = $this->walker->valid ? entry_keytoid($this->walker->current_key()) : false;
|
||||
|
||||
if ($id)
|
||||
$label = $this->local_index[$id]['subject'];
|
||||
else
|
||||
if ($id) {
|
||||
$label = $this->walker->current_value();
|
||||
} else {
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return array($label, $id);
|
||||
|
||||
}
|
||||
@ -490,14 +499,9 @@
|
||||
function getPrevPage() {
|
||||
|
||||
if ($this->single) {
|
||||
return false;
|
||||
|
||||
$id = $this->_getOffsetId(-1, $this->params->start);
|
||||
|
||||
if ($id)
|
||||
$label = $this->local_index[$id]['subject'];
|
||||
else
|
||||
return false;
|
||||
$id = $this->previd;
|
||||
$label = $this->preventry['subject'];
|
||||
|
||||
return array($label, $id);
|
||||
|
||||
|
@ -205,7 +205,7 @@ class Plugin_PrettyURLs {
|
||||
} else {
|
||||
// a bit hackish: we make up a fake url when there is no match,
|
||||
// so that at the higher level the system will 404...
|
||||
$this->fp_params['entry'] = 'entry000000-000000';
|
||||
$this->fp_params['entry'] = 'a';
|
||||
}
|
||||
} else {
|
||||
$this->fp_params['entry'] = $matches[1];
|
||||
|
Loading…
x
Reference in New Issue
Block a user