Optimisation (création de méthodes cluster) pour 'lightdb'
This commit is contained in:
parent
d3d7921dbc
commit
2cb352b4bb
116
automate.php
116
automate.php
|
@ -86,22 +86,46 @@
|
|||
//
|
||||
// }
|
||||
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
|
||||
$req = new ModuleRequest('download/phone', array('subjects'=>array(1, 273, 341)));
|
||||
|
||||
$res = $req->download();
|
||||
|
||||
if( $res->error != ManagerError::Success )
|
||||
var_dump( ManagerError::explicit($res->error) );
|
||||
|
||||
var_dump($res);
|
||||
|
||||
|
||||
/* [4] Test download via AJAX
|
||||
=========================================================*/
|
||||
// $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
|
||||
// $req = new ModuleRequest('download/phone', array('subjects'=>array(1, 273, 341)));
|
||||
//
|
||||
// $res = $req->download();
|
||||
//
|
||||
// if( $res->error != ManagerError::Success )
|
||||
// var_dump( ManagerError::explicit($res->error) );
|
||||
//
|
||||
// var_dump($res);
|
||||
|
||||
|
||||
// $start = microtime(true);
|
||||
// $f = new SplFileObject('compress.zlib://'.__ROOT__.'/tmp/test1.gz', 'w');
|
||||
// $f->fwrite('SOME TEXT');
|
||||
// $f=null;
|
||||
// var_dump('writing time : '.(microtime(true)-$start));
|
||||
//
|
||||
//
|
||||
// $start = microtime(true);
|
||||
// $f2 = new SplFileObject('compress.zlib://'.__ROOT__.'/tmp/test1.gz', 'r');
|
||||
// $read = $f2->fgets();
|
||||
// $f2=null;
|
||||
// var_dump('reading time : '.(microtime(true)-$start));
|
||||
// var_dump($read);
|
||||
//
|
||||
// exit();
|
||||
|
||||
|
||||
/* [4] Analyse des performances de `lightdb`
|
||||
=========================================================*/
|
||||
// $start = microtime(true);
|
||||
// $db = new lightdb('test1', __ROOT__.'/tmp/');
|
||||
|
||||
/* (0) Création des objets à insérer */
|
||||
//
|
||||
// /* (0) Création des objets à insérer */
|
||||
// $object_10 = array();
|
||||
// for( $i = 0 ; $i < 10 ; $i++ )
|
||||
// $object_10["key-$i-"] = "value-$i-";
|
||||
|
@ -118,36 +142,50 @@
|
|||
// $o1000len = strlen( json_encode($object_1000) );
|
||||
|
||||
|
||||
|
||||
/* (1) Insertion de 1000 données */
|
||||
// {1} Insertion d'objects de taille 10 //
|
||||
// var_dump("Inserting 1000* object_10($o10len)");
|
||||
// $start = microtime(true);
|
||||
//
|
||||
// $data = array();
|
||||
// for( $i = 0 ; $i < 1000 ; $i++ )
|
||||
// $db->insert("object-10-$i", $object_10);
|
||||
// // $db->insert("object-10-$i", $object_10);
|
||||
// $data["object-10-$i"] = $object_10;
|
||||
//
|
||||
// $db->insertAll($data);
|
||||
//
|
||||
// $stop = microtime(true);
|
||||
// var_dump('1000 lines inserted in '.($stop-$start).' sec.');
|
||||
// var_dump('1000 lines inserted in '.($stop-$start).' sec.'); echo '<br>';
|
||||
//
|
||||
// // {2} Insertion d'objects de taille 100 //
|
||||
// var_dump("Inserting 1000* object_100($o100len)");
|
||||
// $start = microtime(true);
|
||||
//
|
||||
//
|
||||
// $data = array();
|
||||
// for( $i = 0 ; $i < 1000 ; $i++ )
|
||||
// $db->insert("object-100-$i", $object_100);
|
||||
// // $db->insert("object-100-$i", $object_100);
|
||||
// $data["object-100-$i"] = $object_100;
|
||||
//
|
||||
// $db->insertAll($data);
|
||||
//
|
||||
// $stop = microtime(true);
|
||||
// var_dump('1000 lines inserted in '.($stop-$start).' sec.');
|
||||
// var_dump('1000 lines inserted in '.($stop-$start).' sec.'); echo '<br>';
|
||||
//
|
||||
// // {3} Insertion d'objects de taille 1000 //
|
||||
// var_dump("Inserting 1000* object_1000($o1000len)");
|
||||
// $start = microtime(true);
|
||||
//
|
||||
// $data = array();
|
||||
// for( $i = 0 ; $i < 1000 ; $i++ )
|
||||
// $db->insert("object-1000-$i", $object_1000);
|
||||
// // $db->insert("object-1000-$i", $object_1000);
|
||||
// $data["object-1000-$i"] = $object_1000;
|
||||
//
|
||||
// $db->insertAll($data);
|
||||
//
|
||||
// $stop = microtime(true);
|
||||
// var_dump('1000 lines inserted in '.($stop-$start).' sec.');
|
||||
// var_dump('1000 lines inserted in '.($stop-$start).' sec.'); echo '<br>';
|
||||
|
||||
/* (2) Récupération de 1000 données */
|
||||
// {1} Récupération d'objects de taille 10 //
|
||||
|
@ -158,7 +196,7 @@
|
|||
// $db->fetch("object-10-$i");
|
||||
//
|
||||
// $stop = microtime(true);
|
||||
// var_dump('1000 lines fetched in '.($stop-$start).' sec.');
|
||||
// var_dump('1000 lines fetched in '.($stop-$start).' sec.'); echo '<br>';
|
||||
//
|
||||
// // {2} Récupération d'objects de taille 100 //
|
||||
// var_dump("Fetching 1000* object_100($o100len)");
|
||||
|
@ -168,7 +206,7 @@
|
|||
// $db->fetch("object-100-$i");
|
||||
//
|
||||
// $stop = microtime(true);
|
||||
// var_dump('1000 lines fetched in '.($stop-$start).' sec.');
|
||||
// var_dump('1000 lines fetched in '.($stop-$start).' sec.'); echo '<br>';
|
||||
//
|
||||
// // {3} Récupération d'objects de taille 1000 //
|
||||
// var_dump("Fetching 1000* object_1000($o1000len)");
|
||||
|
@ -178,42 +216,48 @@
|
|||
// $db->fetch("object-1000-$i");
|
||||
//
|
||||
// $stop = microtime(true);
|
||||
// var_dump('1000 lines fetched in '.($stop-$start).' sec.');
|
||||
// var_dump('1000 lines fetched in '.($stop-$start).' sec.'); echo '<br>';
|
||||
|
||||
|
||||
/* (3) Récupération de 1000 données */
|
||||
// {1} Récupération d'objects de taille 10 //
|
||||
// var_dump("Deleting 1000* object_10($o10len)");
|
||||
// $start = microtime(true);
|
||||
/* (3) Suppression de 1000 données */
|
||||
// {1} Suppression d'objects de taille 10 //
|
||||
// var_dump("Deleting 10* object_10($o10len)");
|
||||
//
|
||||
// $keys = array();
|
||||
// for( $i = 0 ; $i < 1000 ; $i++ )
|
||||
// $db->delete("object-10-$i");
|
||||
// array_push($keys, "object-10-$i");
|
||||
//
|
||||
// $start = microtime(true);
|
||||
// $db->deleteAll($keys);
|
||||
// $stop = microtime(true);
|
||||
// var_dump('1000 lines deleted in '.($stop-$start).' sec.');
|
||||
//
|
||||
// // {2} Récupération d'objects de taille 100 //
|
||||
// var_dump('10 lines deleted in '.($stop-$start).' sec.'); echo '<br>';
|
||||
|
||||
|
||||
// // {2} Suppression d'objects de taille 100 //
|
||||
// var_dump("Deleting 1000* object_100($o100len)");
|
||||
// $start = microtime(true);
|
||||
//
|
||||
// $keys = array();
|
||||
// for( $i = 0 ; $i < 1000 ; $i++ )
|
||||
// $db->delete("object-100-$i");
|
||||
// array_push($keys, "object-100-$i");
|
||||
//
|
||||
// $start = microtime(true);
|
||||
// $db->deleteAll($keys);
|
||||
// $stop = microtime(true);
|
||||
// var_dump('1000 lines deleted in '.($stop-$start).' sec.');
|
||||
//
|
||||
// // {3} Récupération d'objects de taille 1000 //
|
||||
// var_dump('1000 lines deleted in '.($stop-$start).' sec.'); echo '<br>';
|
||||
|
||||
|
||||
// // {3} Suppression d'objects de taille 1000 //
|
||||
// var_dump("Deleting 1000* object_1000($o1000len)");
|
||||
// $start = microtime(true);
|
||||
//
|
||||
|
||||
// $keys = array();
|
||||
// for( $i = 0 ; $i < 1000 ; $i++ )
|
||||
// $db->delete("object-1000-$i");
|
||||
// array_push($keys, "object-1000-$i");
|
||||
//
|
||||
// $start = microtime(true);
|
||||
// $db->deleteAll($keys);
|
||||
// $stop = microtime(true);
|
||||
// var_dump('1000 lines deleted in '.($stop-$start).' sec.');
|
||||
//
|
||||
// $db->close();
|
||||
|
||||
// var_dump('total execution time : '.(microtime(true)-$start).' sec');
|
||||
|
||||
?>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
if( !is_null($json) ){
|
||||
|
||||
/* (2) Gestion de la config si server local ou remote */
|
||||
if( !checkdnsrr($_SERVER['SERVER_NAME'], 'NS') )
|
||||
if( !isset($_SERVER['SERVER_NAME']) || !checkdnsrr($_SERVER['SERVER_NAME'], 'NS') )
|
||||
$config = $json['local'];
|
||||
else
|
||||
$config = $json['remote'];
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
public function __construct($dbname, $root=null){
|
||||
/* [0] On récupère les attributs
|
||||
=========================================================*/
|
||||
$this->root = is_null($root) ? self::$default_root.'/' : $root;
|
||||
$this->root = is_null($root) ? self::$default_root.'/' : $root;
|
||||
$this->dbname = $dbname;
|
||||
$this->dir = $this->root.$dbname.'/';
|
||||
|
||||
|
@ -131,30 +131,109 @@
|
|||
}
|
||||
|
||||
|
||||
/* RENVOIE LES DONNEES ASSOCIEES A UNE CLE DONNEE
|
||||
/* INSERTION D'UNE ENTREE DANS LA BASE DE DONNEES
|
||||
*
|
||||
* @key<String> Clé associée à la valeur à récupérer
|
||||
* @dataset<Array> Tableau de 'clés'->'valeurs' à insérer
|
||||
* @data<mixed*> Objet qui sera enregistré dans la base
|
||||
*
|
||||
* @return data<mixed*> Renvoie la valeur associée à la clé, FALSE si erreur
|
||||
* @return status<Boolean> Retourne TRUE si tout s'est bien passé, sinon FALSE
|
||||
*
|
||||
*/
|
||||
public function fetch($key){
|
||||
/* (1) On vérifie que la clé existe bien */
|
||||
if( !array_key_exists($key, $this->index) )
|
||||
return false;
|
||||
public function insertAll($dataset){
|
||||
/* (1) On vérifie que la clé est unique */
|
||||
foreach($dataset as $key=>$data)
|
||||
if( array_key_exists($key, $this->index) )
|
||||
unset($dataset[$key]);
|
||||
|
||||
/* (2) On récupère la ligne */
|
||||
$line = $this->index[$key]['line'];
|
||||
|
||||
/* (3) On récupère le contenu */
|
||||
$this->driver->seek($line);
|
||||
$json = json_decode( $this->driver->current(), true );
|
||||
/* (2) On ajoute les données aux fichier */
|
||||
$this->driver->seek($this->line);
|
||||
foreach($dataset as $key=>$data){
|
||||
$json_data = json_encode($data);
|
||||
$this->line++;
|
||||
$written = $this->driver->fwrite( $json_data.PHP_EOL );
|
||||
|
||||
// Si erreur de parsage
|
||||
if( is_null($json) )
|
||||
return false;
|
||||
|
||||
return $json;
|
||||
/* (3) On enregistre les index */
|
||||
$this->index[$key] = array(
|
||||
'line' => $this->line - 1,
|
||||
'hash' => sha1($json_data)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (4) On enregistre le fichier index */
|
||||
$fIndex = new \SplFileObject($this->dir.'index', 'w');
|
||||
$fIndex->fwrite( json_encode($this->index) );
|
||||
$fIndex = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* RENVOIE LES DONNEES ASSOCIEES A UNE CLE DONNEE
|
||||
*
|
||||
* @key<String> Clé associée à la valeur à récupérer
|
||||
*
|
||||
* @return data<mixed*> Renvoie la valeur associée à la clé, FALSE si erreur
|
||||
*
|
||||
*/
|
||||
public function fetch($key){
|
||||
/* (1) On vérifie que la clé existe bien */
|
||||
if( !array_key_exists($key, $this->index) )
|
||||
return false;
|
||||
|
||||
/* (2) On récupère la ligne */
|
||||
$line = $this->index[$key]['line'];
|
||||
|
||||
/* (3) On récupère le contenu */
|
||||
$this->driver->seek($line);
|
||||
$json = json_decode( $this->driver->current(), true );
|
||||
|
||||
// Si erreur de parsage
|
||||
if( is_null($json) )
|
||||
return false;
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* RENVOIE LES DONNEES ASSOCIEES AUX CLES DONNEES
|
||||
*
|
||||
* @keys<Array> Clés associées aux valeurs à récupérer
|
||||
*
|
||||
* @return data<mixed*> Renvoie les valeurs associées aux clé, ou un tableau vide si erreur
|
||||
*
|
||||
*/
|
||||
public function fetchAll($keys){
|
||||
$data = array();
|
||||
|
||||
/* (0) Pour chaque clé */
|
||||
foreach($keys as $i=>$key){
|
||||
|
||||
/* (1) On ne prend pas en compte les clés qui n'existent pas */
|
||||
if( !array_key_exists($key, $this->index) )
|
||||
continue;
|
||||
|
||||
/* (2) On récupère la ligne */
|
||||
$line = $this->index[$key]['line'];
|
||||
|
||||
/* (3) On récupère le contenu */
|
||||
$this->driver->seek($line);
|
||||
$json = json_decode( $this->driver->current(), true );
|
||||
|
||||
/* (4) Si pas d'erreur de parsage, On enregistre */
|
||||
if( !is_null($json) )
|
||||
$data[$key] = $json;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
|
@ -216,6 +295,104 @@
|
|||
|
||||
|
||||
|
||||
/* SUPPRIME PLUSIEURS ENTREES DE CLES DONNEES DE LA BASE DE DONNEES
|
||||
*
|
||||
* @keys<Array> Clés des entrées à supprimer
|
||||
*
|
||||
* @return status<Boolean> Retourne TRUE si tout s'est bien passé, sinon FALSE
|
||||
*
|
||||
*/
|
||||
public function deleteAll($keys){
|
||||
$keyLines = array();
|
||||
|
||||
/* [1] On récupère la ligne associée à chaque clé
|
||||
=========================================================*/
|
||||
foreach($keys as $k=>$key){
|
||||
/* (1) Si la clé n'existe pas, on passe à la suivante */
|
||||
if( !array_key_exists($key, $this->index) )
|
||||
continue;
|
||||
|
||||
/* (2) On récupère la ligne de la clé */
|
||||
$keyLines[$key] = $this->index[$key]['line'];
|
||||
}
|
||||
|
||||
/* [2] On trie les clés en fonction de leur ligne
|
||||
=========================================================*/
|
||||
$sorted = array();
|
||||
|
||||
// Tant que toute les clés ne sont pas triées
|
||||
while( count($keyLines) > 0 ){
|
||||
// Contiendra la clé de la plus petite valeur
|
||||
$min = null;
|
||||
|
||||
// On cherche la ligne la plus petite
|
||||
foreach($keyLines as $key=>$line)
|
||||
if( is_null($min) || $line < $keyLines[$min] ) // Si valeur inf à min
|
||||
$min = $key;
|
||||
|
||||
// On ajoute la plus petite clé trouvée a la liste
|
||||
$sorted[$min] = $keyLines[$min];
|
||||
|
||||
// On la supprime du tableau à trier
|
||||
unset($keyLines[$min]);
|
||||
|
||||
}
|
||||
|
||||
/* [3] On supprime les lignes à supprimer
|
||||
=========================================================*/
|
||||
/* (1) On réarrange la bd pour supprimer la ligne */
|
||||
$tmpfilename = __ROOT__.'/tmp/'.uniqid().'.dat';
|
||||
$tmpfile = new \SplFileObject($tmpfilename, 'w');
|
||||
$this->driver->seek(0);
|
||||
|
||||
/* (2) On recopie toutes les lignes sauf celles à supprimer dans un fichier temporaire */
|
||||
while( $this->driver->key() < $this->line ){
|
||||
|
||||
// Si la ligne en cours n'est pas dans la liste des lignes à supprimer
|
||||
if( !in_array($this->driver->key(), $sorted) )
|
||||
$tmpfile->fwrite( $this->driver->current() ); // On l'écrit dans le nouveau fichier
|
||||
|
||||
$this->driver->next();
|
||||
}
|
||||
|
||||
$tmpfile = null;
|
||||
|
||||
/* (3) On remplace le fichier original par le fichier temporaire */
|
||||
$this->driver = null;
|
||||
rename($tmpfilename, $this->dir.'data');
|
||||
$this->driver = new \SplFileObject($this->dir.'data', 'r+');
|
||||
|
||||
|
||||
/* [4] On met à jour les index
|
||||
=========================================================*/
|
||||
$step = 0;
|
||||
foreach($sorted as $key=>$line){
|
||||
|
||||
/* (1) On décrémente le nb de lignes */
|
||||
$this->line--;
|
||||
|
||||
/* (2) On supprime la ligne de l'index */
|
||||
unset( $this->index[$key] );
|
||||
|
||||
/* (3) On met à jour les index des lignes déplacées du nombre d'index qu'on a supprimé */
|
||||
foreach($this->index as $i=>$indexData)
|
||||
if( $indexData['line'] > $line-$step )
|
||||
$this->index[$i]['line']--; // on décrémente les lignes au dessus de la ligne supprimée
|
||||
|
||||
$step++;
|
||||
}
|
||||
|
||||
/* (4) On enregistre le fichier index */
|
||||
$fIndex = new \SplFileObject($this->dir.'index', 'w');
|
||||
$fIndex->fwrite( json_encode($this->index) );
|
||||
$fIndex = null;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue