[cpif] r13 - in trunk: . tests varios

svn at argo.es svn at argo.es
Thu Apr 19 12:48:14 CEST 2007


Author: jcea
Date: Thu Apr 19 12:46:56 2007
New Revision: 13

Log:


Added:
   trunk/tests/
   trunk/tests/ejemplo1.py   (contents, props changed)
      - copied, changed from r11, /trunk/varios/prueba_de_concepto.py
Modified:
   trunk/monitor.py
   trunk/varios/prueba_de_concepto.py

Modified: trunk/monitor.py
==============================================================================
--- trunk/monitor.py	(original)
+++ trunk/monitor.py	Thu Apr 19 12:46:56 2007
@@ -34,7 +34,7 @@
         with self.mutex :
           try : # Nos aseguramos de liberar el lock
             self.conn.abort() # Hacemos limpieza de cache
-            ret=func(*args, **kwargs)
+            ret=func(self.conn,*args, **kwargs)
             self.conn.commit()
             return ret
           except ConflictError :
@@ -47,4 +47,8 @@
             raise
 
     return _monitor
+
+  def get_conn(self) :
+    return self.conn
+
 

Copied: trunk/tests/ejemplo1.py (from r11, /trunk/varios/prueba_de_concepto.py)
==============================================================================
--- /trunk/varios/prueba_de_concepto.py	(original)
+++ trunk/tests/ejemplo1.py	Thu Apr 19 12:46:56 2007
@@ -1,141 +1,156 @@
 #!/usr/bin/env python
 
+# $Id$
+
 # Original en http://www.curiosoperoinutil.com/forum/viewtopic.php?t=3721
 # Mas concretamente http://www.curiosoperoinutil.com/forum/viewtopic.php?p=71941#71941
 # y http://www.curiosoperoinutil.com/forum/viewtopic.php?p=72387#72387
 
+# Modificado para que funcione en nuestro entorno
+
+import os
+os.chdir("..")
+import sys
+sys.path.append(".")
+
+
+from durus.btree import BTree 
+from durus.persistent_dict import PersistentDict 
+
+import storage
+dummy,dummy,monitor=storage.storage_and_monitor("db-test",storage=storage.storage_test)
+
+# La numeracion de los mensajes es global. 
+# Lo primero es crear el arbol de actualizacion de hilos 
+# dicho arbol, indexado por numero de mensaje global, nos indica en que 
+# momento se actualizo, por ultima vez, un hilo concreto 
+# 
+# Por otra parte tenemos otro arbol, indexado por hilo, que 
+# nos indica el ultimo mensaje del mismo 
+# 
+# En principio suponemos que cada hilo solo tiene un mensaje, 
+# para inicializar todos los hilos con "algo". 
 
-from logging import disable 
- disable(9999) 
+hilo2last_msg=BTree() 
+last_msg2hilo=BTree() 
  
- import sys 
- sys.path.append("/export/home/correo/durus-berkeleydbstorage") 
+for i in xrange(1000) : # Hay mil hilos, cada uno con un mensaje. LA NUMERACION ES GLOBAL!!! 
+  hilo2last_msg[i]=i 
+  last_msg2hilo[i]=i 
+ 
+# Al principio suponemos que los usuarios estan "al dia". Es decir, para cada 
+# hilos, han leido todos los mensajes. 
+ 
+# Cada usuario tiene tres datos: 
+# - El ultimo numero de mensaje que "sabe" que ha entrado en los hilos 
+# - La posicion de lectura en cada hilo 
+# - El ultimo mensaje leido en cada hilo con mensajes nuevos 
+# 
+# OPTIMIZACION: Un hilo leido por TODOS los usuarios 
+# no se mantiene (su posicion) en cada usuario, sino en 
+# una estructura global. Es decir, cuando se quiere ver cual 
+# es el numero del ultimo mensaje leido por un usuario en 
+# un hilo concreto, buscamos la posicion de de dicho hilo 
+# en la estructura privada del usuario. Si ahi no aparece nada, 
+# la buscamos en la estructura global, compartida por todos los 
+# usuarios. Esta es una optimizacion de espacio en disco, ya 
+# que en cada usuario solo se guardaran las posiciones de lectura 
+# en los hilos "vivos", mientras que los hilos muertos 
+# se guardan en la estructura global, compartida por todos los 
+# usuarios. 
+
+# En lo que sigue suponemos que todos los usuarios parten de todos 
+# los mensajes leidos, asi que su posicion estara en una estructura 
+# global que no se muestra. Basicamente, lo que se guarda localmente 
+# en cada usuario es su diferencia personal respecto a esa tabla global. 
+ 
+import copy 
+punto_de_lectura_global=copy.deepcopy(hilo2last_msg) 
+ 
+usuarios=BTree() 
+for i in xrange(10000) : # 10.000 usuarios 
+  usuarios[i]=PersistentDict({"ultimo mensaje conocido":999, \
+                              "punto de lectura no leidos":BTree(), \
+                              "punto de lectura":BTree()}) 
+ 
+
+# Una vez inicializado todo, comprometemos la transaccion 
+ at monitor
+def inicializa(conn) :
+  root=conn.get_root()
+  root["usuarios"]=usuarios 
+  root["hilo2last_msg"]=hilo2last_msg 
+  root["last_msg2hilo"]=last_msg2hilo 
+  root["proximo mensaje"]=1000 
+  root["punto de lectura global"]=punto_de_lectura_global 
+  print "Commit inicial..." 
  
- from durus.btree import BTree 
- from durus.persistent_dict import PersistentDict 
- from durus.connection import Connection 
- from berkeleydb_storage import BerkeleyDBStorage 
- 
- datos=Connection(BerkeleyDBStorage("db",durable=False,async_log_write=True)) 
- 
- root=datos.get_root() 
- 
- # La numeracion de los mensajes es global. 
- # Lo primero es crear el arbol de actualizacion de hilos 
- # dicho arbol, indexado por numero de mensaje global, nos indica en que 
- # momento se actualizo, por ultima vez, un hilo concreto 
- # 
- # Por otra parte tenemos otro arbol, indexado por hilo, que 
- # nos indica el ultimo mensaje del mismo 
- # 
- # En principio suponemos que cada hilo solo tiene un mensaje, 
- # para inicializar todos los hilos con "algo". 
- 
- hilo2last_msg=BTree() 
- last_msg2hilo=BTree() 
- 
- for i in xrange(1000) : # Hay mil hilos, cada uno con un mensaje. LA NUMERACION ES GLOBAL!!! 
-   hilo2last_msg[i]=i 
-   last_msg2hilo[i]=i 
- 
- # Al principio suponemos que los usuarios estan "al dia". Es decir, para cada 
- # hilos, han leido todos los mensajes. 
- 
- # Cada usuario tiene tres datos: 
- # - El ultimo numero de mensaje que "sabe" que ha entrado en los hilos 
- # - La posicion de lectura en cada hilo 
- # - El ultimo mensaje leido en cada hilo con mensajes nuevos 
- # 
- # OPTIMIZACION: Un hilo leido por TODOS los usuarios 
- # no se mantiene (su posicion) en cada usuario, sino en 
- # una estructura global. Es decir, cuando se quiere ver cual 
- # es el numero del ultimo mensaje leido por un usuario en 
- # un hilo concreto, buscamos la posicion de de dicho hilo 
- # en la estructura privada del usuario. Si ahi no aparece nada, 
- # la buscamos en la estructura global, compartida por todos los 
- # usuarios. Esta es una optimizacion de espacio en disco, ya 
- # que en cada usuario solo se guardaran las posiciones de lectura 
- # en los hilos "vivos", mientras que los hilos muertos 
- # se guardan en la estructura global, compartida por todos los 
- # usuarios. 
- 
- # En lo que sigue suponemos que todos los usuarios parten de todos 
- # los mensajes leidos, asi que su posicion estara en una estructura 
- # global que no se muestra. Basicamente, lo que se guarda localmente 
- # en cada usuario es su diferencia personal respecto a esa tabla global. 
- 
- import copy 
- punto_de_lectura_global=copy.deepcopy(hilo2last_msg) 
- 
- usuarios=BTree() 
- for i in xrange(10000) : # 10.000 usuarios 
-   usuarios[i]=PersistentDict({"ultimo mensaje conocido":999, \ 
-                               "punto de lectura no leidos":BTree(), 
-                               "punto de lectura":BTree()}) 
- 
- # Una vez inicializado todo, comprometemos la transaccion 
- root["usuarios"]=usuarios 
- root["hilo2last_msg"]=hilo2last_msg 
- root["last_msg2hilo"]=last_msg2hilo 
- root["proximo mensaje"]=1000 
- root["punto de lectura global"]=punto_de_lectura_global 
- print "Commit inicial..." 
- datos.commit() 
- 
- 
- # Aqui empieza la chicha. Lo primero que queremos saber es el coste 
- # de insercion de un mensaje nuevo. 
- 
- import time 
- from random import randint 
- 
- # Elegimos 100 hilos al azar 
- hilos=[randint(0,999) for i in xrange(100)] # Insertamos 100 mensajes nuevos en hilos al azar 
- t=time.time() 
- for hilo in hilos : # Lo que sigue se puede optimizar bastante, pero ya vuela... 
-   num_msg=root["proximo mensaje"] 
-   root["proximo mensaje"]+=1 
-   last=root["hilo2last_msg"][hilo] 
-   root["hilo2last_msg"][hilo]=num_msg 
-   del root["last_msg2hilo"][last] 
-   root["last_msg2hilo"][num_msg]=hilo 
-   datos.commit()  # Comprometemos esa transaccion... 
- print "Realizamos %f inserciones por segundo" %(100/(time.time()-t)) 
- 
- 
- # Bien, ahora un usuario quiere ver que hilos no ha leido, y movese al ultimo 
- # mensaje no leido de cada uno de ellos. 
- # Observese que este caso es MUY pesimista, ya que puede haber hasta 100 
- # hilos con mensajes nuevos, lo que es poco realista. El tiempo REAL 
- # es propocional al numero de hilos actualizados, no al numero de mensajes 
- # posteados. Es decir, si se han actualizado 100 hilos con un unico mensaje 
- # mas que en el caso normal de que se hayan actualizado unos pocos hilos, 
- # cada uno de ellos con varios mensajes. 
- # Pero vamos a ser muy pesimistas y suponer que el numero de hilos actualizados 
- # es enorme. 
- 
- t=time.time() 
- for usernum in xrange(1000) : # Probamos a hacer login de los primeros 1000 usuarios 
-   usuario=root["usuarios"][usernum] 
- 
- # Lo que sigue es un poco "raro" por una limitacion de la version actual de 
- # durus. En Durus 3.7, actualmente en beta, podremos iterar sobre intervalos abiertos... 
-   l=usuario["ultimo mensaje conocido"] 
-   posicion_hilos_no_leidos=usuario["punto de lectura no leidos"] 
-   posicion_hilos=usuario["punto de lectura"] 
-   punto_de_lectura_global=root["punto de lectura global"] 
- 
-   for last,hilo in root["last_msg2hilo"].items_backward() : 
-     if last<l : # Hemos terminado. Esto sera mas simple en Durus 3.7 
-       usuario["ultimo mensaje conocido"]=root["last_msg2hilo"].get_max_item()[0] 
-       datos.commit() 
-       break 
-     # Vemos cual es el ultimo leido para ese hilo 
-     ultimo=posicion_hilos.get(hilo,None) # Esta es la optimizacion de hilos que todo el mundo ha leido ya... 
-     if ultimo==None : ultimo=punto_de_lectura_global[hilo] 
-     if ultimo < last : # Este hilo tiene mensajes nuevos... 
-       posicion_hilos_no_leidos[hilo]=ultimo # Lo marcamos como pendiente de leer y nos vamos al ultimo que hemos leido 
+inicializa()
+
+
  
- print "En un caso muy pesimista, tenemos %f actualizaciones de hilos no leidos por segundo" %(1000/(time.time()-t))
+# Aqui empieza la chicha. Lo primero que queremos saber es el coste 
+# de insercion de un mensaje nuevo. 
+ 
+import time 
+from random import randint 
+ 
+ at monitor
+def mete_mensajes(conn) :
+  root=conn.get_root()
+  # Elegimos 100 hilos al azar 
+  hilos=[randint(0,999) for i in xrange(100)] # Insertamos 100 mensajes nuevos en hilos al azar 
+  t=time.time() 
+  for hilo in hilos : # Lo que sigue se puede optimizar bastante, pero ya vuela... 
+    num_msg=root["proximo mensaje"] 
+    root["proximo mensaje"]+=1 
+    last=root["hilo2last_msg"][hilo] 
+    root["hilo2last_msg"][hilo]=num_msg 
+    del root["last_msg2hilo"][last] 
+    root["last_msg2hilo"][num_msg]=hilo 
+
+t=time.time()
+mete_mensajes()
+print "Realizamos %f inserciones por segundo" %(100/(time.time()-t))
+
+ 
+ 
+# Bien, ahora un usuario quiere ver que hilos no ha leido, y movese al ultimo 
+# mensaje no leido de cada uno de ellos. 
+# Observese que este caso es MUY pesimista, ya que puede haber hasta 100 
+# hilos con mensajes nuevos, lo que es poco realista. El tiempo REAL 
+# es propocional al numero de hilos actualizados, no al numero de mensajes 
+# posteados. Es decir, si se han actualizado 100 hilos con un unico mensaje 
+# mas que en el caso normal de que se hayan actualizado unos pocos hilos, 
+# cada uno de ellos con varios mensajes. 
+# Pero vamos a ser muy pesimistas y suponer que el numero de hilos actualizados 
+# es enorme. 
+
+ at monitor
+def actualiza_usuarios(conn) :
+  root=conn.get_root()
+  for usernum in xrange(1000) : # Probamos a hacer login de los primeros 1000 usuarios 
+    usuario=root["usuarios"][usernum] 
+
+# Lo que sigue es un poco "raro" por una limitacion de la version actual de 
+# durus. En Durus 3.7, actualmente en beta, podremos iterar sobre intervalos abiertos... 
+    l=usuario["ultimo mensaje conocido"] 
+    posicion_hilos_no_leidos=usuario["punto de lectura no leidos"] 
+    posicion_hilos=usuario["punto de lectura"] 
+    punto_de_lectura_global=root["punto de lectura global"] 
+
+    for last,hilo in root["last_msg2hilo"].items_backward() : 
+      if last<l : # Hemos terminado. Esto sera mas simple en Durus 3.7 
+        usuario["ultimo mensaje conocido"]=root["last_msg2hilo"].get_max_item()[0] 
+        break 
+      # Vemos cual es el ultimo leido para ese hilo 
+      ultimo=posicion_hilos.get(hilo,None) # Esta es la optimizacion de hilos que todo el mundo ha leido ya... 
+      if ultimo==None : ultimo=punto_de_lectura_global[hilo] 
+      if ultimo < last : # Este hilo tiene mensajes nuevos... 
+        posicion_hilos_no_leidos[hilo]=ultimo # Lo marcamos como pendiente de leer y nos vamos al ultimo que hemos leido 
+
+t=time.time()
+actualiza_usuarios()
+print "En un caso muy pesimista, tenemos %f actualizaciones de hilos no leidos por segundo" %(1000/(time.time()-t))
 
 

Modified: trunk/varios/prueba_de_concepto.py
==============================================================================
--- trunk/varios/prueba_de_concepto.py	(original)
+++ trunk/varios/prueba_de_concepto.py	Thu Apr 19 12:46:56 2007
@@ -6,136 +6,136 @@
 
 
 from logging import disable 
- disable(9999) 
+disable(9999) 
  
- import sys 
- sys.path.append("/export/home/correo/durus-berkeleydbstorage") 
+import sys 
+sys.path.append("/export/home/correo/durus-berkeleydbstorage") 
  
- from durus.btree import BTree 
- from durus.persistent_dict import PersistentDict 
- from durus.connection import Connection 
- from berkeleydb_storage import BerkeleyDBStorage 
- 
- datos=Connection(BerkeleyDBStorage("db",durable=False,async_log_write=True)) 
- 
- root=datos.get_root() 
- 
- # La numeracion de los mensajes es global. 
- # Lo primero es crear el arbol de actualizacion de hilos 
- # dicho arbol, indexado por numero de mensaje global, nos indica en que 
- # momento se actualizo, por ultima vez, un hilo concreto 
- # 
- # Por otra parte tenemos otro arbol, indexado por hilo, que 
- # nos indica el ultimo mensaje del mismo 
- # 
- # En principio suponemos que cada hilo solo tiene un mensaje, 
- # para inicializar todos los hilos con "algo". 
- 
- hilo2last_msg=BTree() 
- last_msg2hilo=BTree() 
- 
- for i in xrange(1000) : # Hay mil hilos, cada uno con un mensaje. LA NUMERACION ES GLOBAL!!! 
-   hilo2last_msg[i]=i 
-   last_msg2hilo[i]=i 
- 
- # Al principio suponemos que los usuarios estan "al dia". Es decir, para cada 
- # hilos, han leido todos los mensajes. 
- 
- # Cada usuario tiene tres datos: 
- # - El ultimo numero de mensaje que "sabe" que ha entrado en los hilos 
- # - La posicion de lectura en cada hilo 
- # - El ultimo mensaje leido en cada hilo con mensajes nuevos 
- # 
- # OPTIMIZACION: Un hilo leido por TODOS los usuarios 
- # no se mantiene (su posicion) en cada usuario, sino en 
- # una estructura global. Es decir, cuando se quiere ver cual 
- # es el numero del ultimo mensaje leido por un usuario en 
- # un hilo concreto, buscamos la posicion de de dicho hilo 
- # en la estructura privada del usuario. Si ahi no aparece nada, 
- # la buscamos en la estructura global, compartida por todos los 
- # usuarios. Esta es una optimizacion de espacio en disco, ya 
- # que en cada usuario solo se guardaran las posiciones de lectura 
- # en los hilos "vivos", mientras que los hilos muertos 
- # se guardan en la estructura global, compartida por todos los 
- # usuarios. 
- 
- # En lo que sigue suponemos que todos los usuarios parten de todos 
- # los mensajes leidos, asi que su posicion estara en una estructura 
- # global que no se muestra. Basicamente, lo que se guarda localmente 
- # en cada usuario es su diferencia personal respecto a esa tabla global. 
- 
- import copy 
- punto_de_lectura_global=copy.deepcopy(hilo2last_msg) 
- 
- usuarios=BTree() 
- for i in xrange(10000) : # 10.000 usuarios 
-   usuarios[i]=PersistentDict({"ultimo mensaje conocido":999, \ 
-                               "punto de lectura no leidos":BTree(), 
-                               "punto de lectura":BTree()}) 
- 
- # Una vez inicializado todo, comprometemos la transaccion 
- root["usuarios"]=usuarios 
- root["hilo2last_msg"]=hilo2last_msg 
- root["last_msg2hilo"]=last_msg2hilo 
- root["proximo mensaje"]=1000 
- root["punto de lectura global"]=punto_de_lectura_global 
- print "Commit inicial..." 
- datos.commit() 
- 
- 
- # Aqui empieza la chicha. Lo primero que queremos saber es el coste 
- # de insercion de un mensaje nuevo. 
- 
- import time 
- from random import randint 
- 
- # Elegimos 100 hilos al azar 
- hilos=[randint(0,999) for i in xrange(100)] # Insertamos 100 mensajes nuevos en hilos al azar 
- t=time.time() 
- for hilo in hilos : # Lo que sigue se puede optimizar bastante, pero ya vuela... 
-   num_msg=root["proximo mensaje"] 
-   root["proximo mensaje"]+=1 
-   last=root["hilo2last_msg"][hilo] 
-   root["hilo2last_msg"][hilo]=num_msg 
-   del root["last_msg2hilo"][last] 
-   root["last_msg2hilo"][num_msg]=hilo 
-   datos.commit()  # Comprometemos esa transaccion... 
- print "Realizamos %f inserciones por segundo" %(100/(time.time()-t)) 
- 
- 
- # Bien, ahora un usuario quiere ver que hilos no ha leido, y movese al ultimo 
- # mensaje no leido de cada uno de ellos. 
- # Observese que este caso es MUY pesimista, ya que puede haber hasta 100 
- # hilos con mensajes nuevos, lo que es poco realista. El tiempo REAL 
- # es propocional al numero de hilos actualizados, no al numero de mensajes 
- # posteados. Es decir, si se han actualizado 100 hilos con un unico mensaje 
- # mas que en el caso normal de que se hayan actualizado unos pocos hilos, 
- # cada uno de ellos con varios mensajes. 
- # Pero vamos a ser muy pesimistas y suponer que el numero de hilos actualizados 
- # es enorme. 
- 
- t=time.time() 
- for usernum in xrange(1000) : # Probamos a hacer login de los primeros 1000 usuarios 
-   usuario=root["usuarios"][usernum] 
- 
- # Lo que sigue es un poco "raro" por una limitacion de la version actual de 
- # durus. En Durus 3.7, actualmente en beta, podremos iterar sobre intervalos abiertos... 
-   l=usuario["ultimo mensaje conocido"] 
-   posicion_hilos_no_leidos=usuario["punto de lectura no leidos"] 
-   posicion_hilos=usuario["punto de lectura"] 
-   punto_de_lectura_global=root["punto de lectura global"] 
- 
-   for last,hilo in root["last_msg2hilo"].items_backward() : 
-     if last<l : # Hemos terminado. Esto sera mas simple en Durus 3.7 
-       usuario["ultimo mensaje conocido"]=root["last_msg2hilo"].get_max_item()[0] 
-       datos.commit() 
-       break 
-     # Vemos cual es el ultimo leido para ese hilo 
-     ultimo=posicion_hilos.get(hilo,None) # Esta es la optimizacion de hilos que todo el mundo ha leido ya... 
-     if ultimo==None : ultimo=punto_de_lectura_global[hilo] 
-     if ultimo < last : # Este hilo tiene mensajes nuevos... 
-       posicion_hilos_no_leidos[hilo]=ultimo # Lo marcamos como pendiente de leer y nos vamos al ultimo que hemos leido 
- 
- print "En un caso muy pesimista, tenemos %f actualizaciones de hilos no leidos por segundo" %(1000/(time.time()-t))
+from durus.btree import BTree 
+from durus.persistent_dict import PersistentDict 
+from durus.connection import Connection 
+from berkeleydb_storage import BerkeleyDBStorage 
+
+datos=Connection(BerkeleyDBStorage("db",durable=False,async_log_write=True)) 
+ 
+root=datos.get_root() 
+ 
+# La numeracion de los mensajes es global. 
+# Lo primero es crear el arbol de actualizacion de hilos 
+# dicho arbol, indexado por numero de mensaje global, nos indica en que 
+# momento se actualizo, por ultima vez, un hilo concreto 
+# 
+# Por otra parte tenemos otro arbol, indexado por hilo, que 
+# nos indica el ultimo mensaje del mismo 
+# 
+# En principio suponemos que cada hilo solo tiene un mensaje, 
+# para inicializar todos los hilos con "algo". 
+
+hilo2last_msg=BTree() 
+last_msg2hilo=BTree() 
+ 
+for i in xrange(1000) : # Hay mil hilos, cada uno con un mensaje. LA NUMERACION ES GLOBAL!!! 
+  hilo2last_msg[i]=i 
+  last_msg2hilo[i]=i 
+ 
+# Al principio suponemos que los usuarios estan "al dia". Es decir, para cada 
+# hilos, han leido todos los mensajes. 
+ 
+# Cada usuario tiene tres datos: 
+# - El ultimo numero de mensaje que "sabe" que ha entrado en los hilos 
+# - La posicion de lectura en cada hilo 
+# - El ultimo mensaje leido en cada hilo con mensajes nuevos 
+# 
+# OPTIMIZACION: Un hilo leido por TODOS los usuarios 
+# no se mantiene (su posicion) en cada usuario, sino en 
+# una estructura global. Es decir, cuando se quiere ver cual 
+# es el numero del ultimo mensaje leido por un usuario en 
+# un hilo concreto, buscamos la posicion de de dicho hilo 
+# en la estructura privada del usuario. Si ahi no aparece nada, 
+# la buscamos en la estructura global, compartida por todos los 
+# usuarios. Esta es una optimizacion de espacio en disco, ya 
+# que en cada usuario solo se guardaran las posiciones de lectura 
+# en los hilos "vivos", mientras que los hilos muertos 
+# se guardan en la estructura global, compartida por todos los 
+# usuarios. 
+
+# En lo que sigue suponemos que todos los usuarios parten de todos 
+# los mensajes leidos, asi que su posicion estara en una estructura 
+# global que no se muestra. Basicamente, lo que se guarda localmente 
+# en cada usuario es su diferencia personal respecto a esa tabla global. 
+ 
+import copy 
+punto_de_lectura_global=copy.deepcopy(hilo2last_msg) 
+ 
+usuarios=BTree() 
+for i in xrange(10000) : # 10.000 usuarios 
+  usuarios[i]=PersistentDict({"ultimo mensaje conocido":999, \
+                              "punto de lectura no leidos":BTree(), \
+                              "punto de lectura":BTree()}) 
+ 
+# Una vez inicializado todo, comprometemos la transaccion 
+root["usuarios"]=usuarios 
+root["hilo2last_msg"]=hilo2last_msg 
+root["last_msg2hilo"]=last_msg2hilo 
+root["proximo mensaje"]=1000 
+root["punto de lectura global"]=punto_de_lectura_global 
+print "Commit inicial..." 
+datos.commit() 
+ 
+ 
+# Aqui empieza la chicha. Lo primero que queremos saber es el coste 
+# de insercion de un mensaje nuevo. 
+ 
+import time 
+from random import randint 
+ 
+# Elegimos 100 hilos al azar 
+hilos=[randint(0,999) for i in xrange(100)] # Insertamos 100 mensajes nuevos en hilos al azar 
+t=time.time() 
+for hilo in hilos : # Lo que sigue se puede optimizar bastante, pero ya vuela... 
+  num_msg=root["proximo mensaje"] 
+  root["proximo mensaje"]+=1 
+  last=root["hilo2last_msg"][hilo] 
+  root["hilo2last_msg"][hilo]=num_msg 
+  del root["last_msg2hilo"][last] 
+  root["last_msg2hilo"][num_msg]=hilo 
+  datos.commit()  # Comprometemos esa transaccion... 
+print "Realizamos %f inserciones por segundo" %(100/(time.time()-t)) 
+ 
+ 
+# Bien, ahora un usuario quiere ver que hilos no ha leido, y movese al ultimo 
+# mensaje no leido de cada uno de ellos. 
+# Observese que este caso es MUY pesimista, ya que puede haber hasta 100 
+# hilos con mensajes nuevos, lo que es poco realista. El tiempo REAL 
+# es propocional al numero de hilos actualizados, no al numero de mensajes 
+# posteados. Es decir, si se han actualizado 100 hilos con un unico mensaje 
+# mas que en el caso normal de que se hayan actualizado unos pocos hilos, 
+# cada uno de ellos con varios mensajes. 
+# Pero vamos a ser muy pesimistas y suponer que el numero de hilos actualizados 
+# es enorme. 
+
+t=time.time() 
+for usernum in xrange(1000) : # Probamos a hacer login de los primeros 1000 usuarios 
+  usuario=root["usuarios"][usernum] 
+
+# Lo que sigue es un poco "raro" por una limitacion de la version actual de 
+# durus. En Durus 3.7, actualmente en beta, podremos iterar sobre intervalos abiertos... 
+  l=usuario["ultimo mensaje conocido"] 
+  posicion_hilos_no_leidos=usuario["punto de lectura no leidos"] 
+  posicion_hilos=usuario["punto de lectura"] 
+  punto_de_lectura_global=root["punto de lectura global"] 
+
+  for last,hilo in root["last_msg2hilo"].items_backward() : 
+    if last<l : # Hemos terminado. Esto sera mas simple en Durus 3.7 
+      usuario["ultimo mensaje conocido"]=root["last_msg2hilo"].get_max_item()[0] 
+      datos.commit() 
+      break 
+    # Vemos cual es el ultimo leido para ese hilo 
+    ultimo=posicion_hilos.get(hilo,None) # Esta es la optimizacion de hilos que todo el mundo ha leido ya... 
+    if ultimo==None : ultimo=punto_de_lectura_global[hilo] 
+    if ultimo < last : # Este hilo tiene mensajes nuevos... 
+      posicion_hilos_no_leidos[hilo]=ultimo # Lo marcamos como pendiente de leer y nos vamos al ultimo que hemos leido 
+
+print "En un caso muy pesimista, tenemos %f actualizaciones de hilos no leidos por segundo" %(1000/(time.time()-t))
 
 



More information about the cpif mailing list