Changeset 5860


Ignore:
Timestamp:
Oct 23, 2008, 9:28:02 AM (15 years ago)
Author:
ole
Message:

Thought of testing hash-collision and found issue with comparison
This is now fixed and tests verified.

Location:
anuga_core/source/anuga/caching
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • anuga_core/source/anuga/caching/caching.py

    r5856 r5860  
    221221    be evaluated. If both evaluate and test are switched on, evaluate takes
    222222    precedence.
     223    ??NOTE: In case of hash collisions, this may return the wrong result as
     224    ??it only checks if *a* cached result is present.
    223225   
    224226  Obtain cache filenames:
     
    13891391  return(val)
    13901392
    1391 # -----------------------------------------------------------------------------
    13921393
    13931394
     
    14021403    """
    14031404
    1404     try:
    1405         identical = (A == B)
    1406     except:
    1407         # E.g. if A and B are circular or otherwise can't be compared.
    1408         identical = False
    1409        
    1410        
    1411     if identical is False:   
    1412         # Use pickle to compare data
    1413         # The native pickler must be used
    1414         # since the faster cPickle does not
    1415         # guarantee a unique translation
    1416        
    1417         import pickle as pickler # Use non-C version here
    1418         #import cPickle as pickler
    1419         identical = (pickler.dumps(A,0) == pickler.dumps(B,0))
    1420 
    1421     return(identical)
    1422 
    1423 
    1424 def old_compare(A, B, ids=None):
    1425     """Safe comparison of general objects
    1426 
    1427     USAGE:
    1428       compare(A,B)
    1429 
    1430     DESCRIPTION:
    1431       Return 1 if A and B they are identical, 0 otherwise
    1432     """
    1433 
    1434     # FIXME (Ole): This is probably obsolete now
    1435    
    14361405    from types import TupleType, ListType, DictType, InstanceType
    1437    
     1406    from Numeric import ArrayType, alltrue   
    14381407   
    14391408    # Keep track of unique id's to protect against infinite recursion
    14401409    if ids is None: ids = {}
    1441 
    14421410
    14431411    # Check if T has already been encountered
     
    14531421   
    14541422   
    1455     #print 'Comparing', A, B, (iA, iB)
    1456     #print ids
    1457     #raw_input()
    1458    
    1459     if type(A) in [TupleType, ListType] and type(B) in [TupleType, ListType]:
     1423    # Check if arguments are of same type
     1424    if type(A) != type(B):
     1425        return False
     1426       
     1427 
     1428    # Compare recursively based on argument type
     1429    if type(A) in [TupleType, ListType]:
    14601430        N = len(A)
    14611431        if len(B) != N:
     
    14661436                if not compare(A[i], B[i], ids):
    14671437                    identical = False; break
    1468                
    1469     elif type(A) == DictType and type(B) == DictType:
     1438                   
     1439    elif type(A) == DictType:
    14701440        if len(A) != len(B):
    14711441            identical = False
    1472         else:   
    1473             identical = True
    1474             for key in A.keys():
    1475                 if not B.has_key(key):
    1476                     identical = False; break
    1477          
    1478                 if not compare(A[key], B[key], ids):
    1479                     identical = False; break     
    1480    
    1481     elif type(A) == type(B) == types.InstanceType:   
     1442        else:                       
     1443            # Make dictionary ordering unique
     1444            a = A.items(); a.sort()   
     1445            b = B.items(); b.sort()
     1446           
     1447            identical = compare(a, b, ids)
     1448           
     1449    elif type(A) == ArrayType:
     1450        # Use element by element comparison
     1451        identical = alltrue(A==B)
     1452
     1453    elif type(A) == InstanceType:
    14821454        # Take care of special case where elements are instances           
    1483         # Base comparison on attributes
    1484                
    1485         a = A.__dict__                 
    1486         b = B.__dict__                             
    1487                
    1488         identical = compare(a, b, ids)               
    1489 
    1490    
    1491        
     1455        # Base comparison on attributes     
     1456        identical = compare(A.__dict__,
     1457                            B.__dict__,
     1458                            ids)
    14921459    else:       
    14931460        # Fall back to general code
     
    14951462            identical = (A == B)
    14961463        except:
    1497             import pickle # Use non-C version here
     1464            import pickle
     1465            # Use pickle to compare data
     1466            # The native pickler must be used
     1467            # since the faster cPickle does not
     1468            # guarantee a unique translation           
    14981469            try:
    14991470                identical = (pickle.dumps(A,0) == pickle.dumps(B,0))
    15001471            except:
    1501                 identical = 0
     1472                identical = False
    15021473
    15031474    # Record result of comparison and return           
     
    15061477    return(identical)
    15071478
     1479   
    15081480# -----------------------------------------------------------------------------
    15091481
  • anuga_core/source/anuga/caching/test_caching.py

    r5856 r5860  
    163163           
    164164
     165    def test_hash_collision(self):
     166        """test_hash_collision(self):
     167       
     168        Test that hash collisons are dealt with correctly
     169        """
     170       
     171        verbose = False
     172       
     173        # Make test input arguments
     174        A0 = arange(5)*1.0
     175        B = ('x', 15)
     176       
     177        # Create different A that hashes to the same address (having the same average)
     178        A1 = array([2.0, 2.0, 2.0, 2.0, 2.0])       
     179       
     180        assert myhash(A0) == myhash(A1)
     181           
     182           
     183        # Test caching
     184        comprange = 2
     185        for comp in range(comprange):
     186       
     187            # Clear
     188            cache(f_numeric, (A0, A0), clear=1,
     189                  compression=comp, verbose=verbose)       
     190            cache(f_numeric, (A1, A1), clear=1,
     191                  compression=comp, verbose=verbose)                         
     192 
     193 
     194            # Evaluate and store
     195            T1 = cache(f_numeric, (A0, A0), evaluate=1,
     196                       compression=comp, verbose=verbose)
     197
     198           
     199            # Check that A1 doesn't trigger retrieval of the previous result
     200            # even though it hashes to the same address
     201            T2 = cache(f_numeric, (A1, A1),
     202                       compression=comp, verbose=verbose)
     203           
     204
     205            #print T1
     206            #print T2
     207            assert T2 != T1
     208
     209           
     210
     211           
     212           
    165213    def test_caching_of_dictionaries(self):
    166214        """test_caching_of_dictionaries
     
    771819#-------------------------------------------------------------
    772820if __name__ == "__main__":
     821    #suite = unittest.makeSuite(Test_Caching, 'test_hash_collision')
    773822    suite = unittest.makeSuite(Test_Caching, 'test')
    774823    runner = unittest.TextTestRunner()
Note: See TracChangeset for help on using the changeset viewer.