From: Steve W. <wai...@us...> - 2001-01-31 03:11:29
|
Update of /cvsroot/phpwiki/phpwiki/lib In directory usw-pr-cvs1:/tmp/cvs-serv32083 Modified Files: dbmlib.php Log Message: Going back to version 1.5, this time with the signature Jan Hidder used for InsertPage() that I removed, thus causing a bug. It feels slower now though. Index: dbmlib.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/dbmlib.php,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** dbmlib.php 2001/01/09 19:02:52 1.6 --- dbmlib.php 2001/01/31 03:11:25 1.7 *************** *** 6,27 **** Database functions: ! OpenDataBase($dbname) ! CloseDataBase($dbi) ! PadSerializedData($data) ! UnPadSerializedData($data) ! RetrievePage($dbi, $pagename, $pagestore) ! InsertPage($dbi, $pagename, $pagehash) SaveCopyToArchive($dbi, $pagename, $pagehash) ! IsWikiPage($dbi, $pagename) ! IsInArchive($dbi, $pagename) ! InitTitleSearch($dbi, $search) ! TitleSearchNextMatch($dbi, &$pos) ! InitFullSearch($dbi, $search) ! FullSearchNextMatch($dbi, &$pos) ! IncreaseHitCount($dbi, $pagename) ! GetHitCount($dbi, $pagename) ! InitMostPopular($dbi, $limit) ! MostPopularNextMatch($dbi, &$res) ! GetAllWikiPagenames($dbi) */ --- 6,23 ---- Database functions: ! OpenDataBase($table) ! CloseDataBase($dbi) ! RetrievePage($dbi, $pagename, $pagestore) ! InsertPage($dbi, $pagename, $pagehash) SaveCopyToArchive($dbi, $pagename, $pagehash) ! IsWikiPage($dbi, $pagename) ! InitTitleSearch($dbi, $search) ! TitleSearchNextMatch($dbi, $res) ! InitFullSearch($dbi, $search) ! FullSearchNextMatch($dbi, $res) ! IncreaseHitCount($dbi, $pagename) ! GetHitCount($dbi, $pagename) ! InitMostPopular($dbi, $limit) ! MostPopularNextMatch($dbi, $res) */ *************** *** 91,99 **** // Either insert or replace a key/value (a page) ! function InsertPage($dbi, $pagename, $pagehash) { $pagedata = PadSerializedData(serialize($pagehash)); ! if (dbminsert($dbi['wiki'], $pagename, $pagedata)) { ! if (dbmreplace($dbi['wiki'], $pagename, $pagedata)) { ExitWiki("Error inserting page '$pagename'"); } --- 87,101 ---- // Either insert or replace a key/value (a page) ! function InsertPage($dbi, $pagename, $pagehash, $pagestore='wiki') { ! ! if ($pagestore == 'wiki') { // a bit of a hack ! $linklist = ExtractWikiPageLinks($pagehash['content']); ! SetWikiPageLinks($dbi, $pagename, $linklist); ! } ! $pagedata = PadSerializedData(serialize($pagehash)); ! if (dbminsert($dbi[$pagestore], $pagename, $pagedata)) { ! if (dbmreplace($dbi[$pagestore], $pagename, $pagedata)) { ExitWiki("Error inserting page '$pagename'"); } *************** *** 102,106 **** ! // for archiving pages to a seperate dbm function SaveCopyToArchive($dbi, $pagename, $pagehash) { global $ArchivePageStore; --- 104,108 ---- ! // for archiving pages to a separate dbm function SaveCopyToArchive($dbi, $pagename, $pagehash) { global $ArchivePageStore; *************** *** 126,129 **** --- 128,163 ---- + function RemovePage($dbi, $pagename) { + + dbmdelete($dbi['wiki'], $pagename); // report error if this fails? + dbmdelete($dbi['archive'], $pagename); // no error if this fails + dbmdelete($dbi['hitcount'], $pagename); // no error if this fails + + $linkinfo = RetrievePage($dbi, $pagename, 'wikilinks'); + + // remove page from fromlinks of pages it had links to + if (is_array($linkinfo)) { // page exists? + $tolinks = $linkinfo['tolinks']; + reset($tolinks); + while (list($tolink, $dummy) = each($tolinks)) { + $tolinkinfo = RetrievePage($dbi, $tolink, 'wikilinks'); + if (is_array($tolinkinfo)) { // page found? + $oldFromlinks = $tolinkinfo['fromlinks']; + $tolinkinfo['fromlinks'] = array(); // erase fromlinks + reset($oldFromlinks); + while (list($fromlink, $dummy) = each($oldFromlinks)) { + if ($fromlink != $pagename) // not to be erased? + $tolinkinfo['fromlinks'][$fromlink] = 1; // put link back + } // put link info back in DBM file + InsertPage($dbi, $tolink, $tolinkinfo, 'wikilinks'); + } + } + + // remove page itself + dbmdelete($dbi['wikilinks'], $pagename); + } + } + + // setup for title-search function InitTitleSearch($dbi, $search) { *************** *** 134,137 **** --- 168,172 ---- } + // iterating through database function TitleSearchNextMatch($dbi, &$pos) { *************** *** 147,150 **** --- 182,186 ---- } + // setup for full-text search function InitFullSearch($dbi, $search) { *************** *** 152,155 **** --- 188,192 ---- } + //iterating through database function FullSearchNextMatch($dbi, &$pos) { *************** *** 170,177 **** } //////////////////////// // new database features - function IncreaseHitCount($dbi, $pagename) { --- 207,214 ---- } + //////////////////////// // new database features function IncreaseHitCount($dbi, $pagename) { *************** *** 184,188 **** } else { // add it, set the hit count to one - // echo "adding $pagename to hitcount...<br>\n"; $count = 1; dbminsert($dbi['hitcount'], $pagename, $count); --- 221,224 ---- *************** *** 190,193 **** --- 226,230 ---- } + function GetHitCount($dbi, $pagename) { *************** *** 207,222 **** // n..$limit results $pagename = dbmfirstkey($dbi['hitcount']); ! $res[$pagename] = dbmfetch($dbi['hitcount'], $pagename); while ($pagename = dbmnextkey($dbi['hitcount'], $pagename)) { ! $res[$pagename] = dbmfetch($dbi['hitcount'], $pagename); ! //echo "got $pagename with value " . $res[$pagename] . "<br>\n"; } ! ! arsort($res); return($res); } function MostPopularNextMatch($dbi, &$res) { --- 244,290 ---- // n..$limit results + // Because sorting all the pages may be a lot of work + // we only get the top $limit. A page is only added if it's score is + // higher than the lowest score in the list. If the list is full then + // one of the pages with the lowest scores is removed. + $pagename = dbmfirstkey($dbi['hitcount']); ! $score = dbmfetch($dbi['hitcount'], $pagename); ! $res = array($pagename => (int) $score); ! $lowest = $score; while ($pagename = dbmnextkey($dbi['hitcount'], $pagename)) { ! $score = dbmfetch($dbi['hitcount'], $pagename); ! if (count($res) < $limit) { // room left in $res? ! if ($score < $lowest) ! $lowest = $score; ! $res[$pagename] = (int) $score; // add page to $res ! } elseif ($score > $lowest) { ! $oldres = $res; // save old result ! $res = array(); ! $removed = 0; // nothing removed yet ! $newlowest = $score; // new lowest score ! $res[$pagename] = (int) $score; // add page to $res ! reset($oldres); ! while(list($pname, $pscore) = each($oldres)) { ! if (!$removed and ($pscore = $lowest)) ! $removed = 1; // don't copy this entry ! else { ! $res[$pname] = (int) $pscore; ! if ($pscore < $newlowest) ! $newlowest = $pscore; ! } ! } ! $lowest = $newlowest; ! } } ! ! arsort($res); // sort ! reset($res); ! return($res); } + function MostPopularNextMatch($dbi, &$res) { *************** *** 224,238 **** // and 'pagename' as the keys - if (count($res) == 0) - return 0; - if (list($pagename, $hits) = each($res)) { - //echo "most popular next match called<br>\n"; - //echo "got $pagename, $hits back<br>\n"; $nextpage = array( "hits" => $hits, "pagename" => $pagename ); - // $dbm_mostpopular_cntr++; return $nextpage; } else { --- 292,300 ---- *************** *** 241,244 **** --- 303,307 ---- } + function GetAllWikiPagenames($dbi) { $namelist = array(); *************** *** 253,256 **** --- 316,482 ---- return $namelist; + } + + + //////////////////////////////////////////// + // functionality for the wikilinks DBM file + + // format of the 'wikilinks' DBM file : + // pagename => + // { tolinks => ( pagename => 1}, fromlinks => { pagename => 1 } } + + // takes a page name, returns array of scored incoming and outgoing links + function GetWikiPageLinks($dbi, $pagename) { + + $linkinfo = RetrievePage($dbi, $pagename, 'wikilinks'); + if (is_array($linkinfo)) { // page exists? + $tolinks = $linkinfo['tolinks']; // outgoing links + $fromlinks = $linkinfo['fromlinks']; // incoming links + } else { // new page, but pages may already point to it + // create info for page + $tolinks = array(); + $fromlinks = array(); + // look up pages that link to $pagename + $pname = dbmfirstkey($dbi['wikilinks']); + while ($pname) { + $linkinfo = RetrievePage($dbi, $pname, 'wikilinks'); + if ($linkinfo['tolinks'][$pagename]) // $pname links to $pagename? + $fromlinks[$pname] = 1; + $pname = dbmnextkey($dbi['wikilinks'], $pname); + } + } + + // get and sort the outgoing links + $outlinks = array(); + reset($tolinks); // look up scores for tolinks + while(list($tolink, $dummy) = each($tolinks)) { + $toPage = RetrievePage($dbi, $tolink, 'wikilinks'); + if (is_array($toPage)) // link to internal page? + $outlinks[$tolink] = count($toPage['fromlinks']); + } + arsort($outlinks); // sort on score + $links['out'] = array(); + reset($outlinks); // convert to right format + while(list($link, $score) = each($outlinks)) + $links['out'][] = array($link, $score); + + // get and sort the incoming links + $inlinks = array(); + reset($fromlinks); // look up scores for fromlinks + while(list($fromlink, $dummy) = each($fromlinks)) { + $fromPage = RetrievePage($dbi, $fromlink, 'wikilinks'); + $inlinks[$fromlink] = count($fromPage['fromlinks']); + } + arsort($inlinks); // sort on score + $links['in'] = array(); + reset($inlinks); // convert to right format + while(list($link, $score) = each($inlinks)) + $links['in'][] = array($link, $score); + + // sort all the incoming and outgoing links + $allLinks = $outlinks; // copy the outlinks + reset($inlinks); // add the inlinks + while(list($key, $value) = each($inlinks)) + $allLinks[$key] = $value; + reset($allLinks); // lookup hits + while(list($key, $value) = each($allLinks)) + $allLinks[$key] = (int) dbmfetch($dbi['hitcount'], $key); + arsort($allLinks); // sort on hits + $links['popular'] = array(); + reset($allLinks); // convert to right format + while(list($link, $hits) = each($allLinks)) + $links['popular'][] = array($link, $hits); + + return $links; + } + + + // takes page name, list of links it contains + // the $linklist is an array where the keys are the page names + function SetWikiPageLinks($dbi, $pagename, $linklist) { + + $cache = array(); + + // Phase 1: fetch the relevant pairs from 'wikilinks' into $cache + // --------------------------------------------------------------- + + // first the info for $pagename + $linkinfo = RetrievePage($dbi, $pagename, 'wikilinks'); + if (is_array($linkinfo)) // page exists? + $cache[$pagename] = $linkinfo; + else { + // create info for page + $cache[$pagename] = array( 'fromlinks' => array(), + 'tolinks' => array() + ); + // look up pages that link to $pagename + $pname = dbmfirstkey($dbi['wikilinks']); + while ($pname) { + $linkinfo = RetrievePage($dbi, $pname, 'wikilinks'); + if ($linkinfo['tolinks'][$pagename]) + $cache[$pagename]['fromlinks'][$pname] = 1; + $pname = dbmnextkey($dbi['wikilinks'], $pname); + } + } + + // then the info for the pages that $pagename used to point to + $oldTolinks = $cache[$pagename]['tolinks']; + reset($oldTolinks); + while (list($link, $dummy) = each($oldTolinks)) { + $linkinfo = RetrievePage($dbi, $link, 'wikilinks'); + if (is_array($linkinfo)) + $cache[$link] = $linkinfo; + } + + // finally the info for the pages that $pagename will point to + reset($linklist); + while (list($link, $dummy) = each($linklist)) { + $linkinfo = RetrievePage($dbi, $link, 'wikilinks'); + if (is_array($linkinfo)) + $cache[$link] = $linkinfo; + } + + // Phase 2: delete the old links + // --------------------------------------------------------------- + + // delete the old tolinks for $pagename + // $cache[$pagename]['tolinks'] = array(); + // (overwritten anyway in Phase 3) + + // remove $pagename from the fromlinks of pages in $oldTolinks + + reset($oldTolinks); + while (list($oldTolink, $dummy) = each($oldTolinks)) { + if ($cache[$oldTolink]) { // links to existing page? + $oldFromlinks = $cache[$oldTolink]['fromlinks']; + $cache[$oldTolink]['fromlinks'] = array(); // erase fromlinks + reset($oldFromlinks); // comp. new fr.links + while (list($fromlink, $dummy) = each($oldFromlinks)) { + if ($fromlink != $pagename) + $cache[$oldTolink]['fromlinks'][$fromlink] = 1; + } + } + } + + // Phase 3: add the new links + // --------------------------------------------------------------- + + // set the new tolinks for $pagename + $cache[$pagename]['tolinks'] = $linklist; + + // add $pagename to the fromlinks of pages in $linklist + reset($linklist); + while (list($link, $dummy) = each($linklist)) { + if ($cache[$link]) // existing page? + $cache[$link]['fromlinks'][$pagename] = 1; + } + + // Phase 4: write $cache back to 'wikilinks' + // --------------------------------------------------------------- + + reset($cache); + while (list($link,$fromAndTolinks) = each($cache)) + InsertPage($dbi, $link, $fromAndTolinks, 'wikilinks'); + } |