Changeset 3596

Show
Ignore:
Timestamp:
10/18/07 13:39:33 (1 year ago)
Author:
mscott
Message:

Merge #63 to trunk.

Introduces SchevoBenchmark?, which provides a measurement tool for measuring the execution time of Schevo benchmark suites and a reporting tool for comparing benchmark runs of different versions of Schevo.

schevo.database2:Database._update_entity

  • Only worry about updating bidirectional links if a related_entities structure was given.
  • Try to avoid removing and re-adding links unnecessarily.
  • Small but measurable performance improvement from these changes.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Schevo/schevo/database2.py

    r3509 r3596  
    855855            # Get old values for use in a potential inversion. 
    856856            old_fields = self._entity_fields(extent_name, oid) 
    857             old_related_entities = self._entity_related_entities( 
    858                 extent_name, oid) 
     857            updating_related = len(related_entities) > 0 
     858            if updating_related: 
     859                old_related_entities = self._entity_related_entities( 
     860                    extent_name, oid) 
     861            else: 
     862                old_related_entities = {} 
    859863            old_rev = entity_map['rev'] 
    860864            # Manage entity references. 
    861             for name, related_entity_set in related_entities.iteritems(): 
    862                 field_id = field_name_id[name] 
    863                 for placeholder in related_entity_set: 
    864                     other_extent_id = placeholder.extent_id 
    865                     other_oid = placeholder.oid 
    866                     nl_append((field_id, other_extent_id, other_oid)) 
     865            if updating_related: 
     866                for name, related_entity_set in related_entities.iteritems(): 
     867                    field_id = field_name_id[name] 
     868                    for placeholder in related_entity_set: 
     869                        other_extent_id = placeholder.extent_id 
     870                        other_oid = placeholder.oid 
     871                        nl_append((field_id, other_extent_id, other_oid)) 
    867872            # Get fields, and set UNASSIGNED for any fields that are 
    868873            # new since the last time the entity was stored. 
    869874            fields_by_id = entity_map['fields'] 
    870             all_field_ids = set(extent_map['field_id_name'].iterkeys()
    871             new_fields = all_field_ids - set(fields_by_id.iterkeys()
     875            all_field_ids = set(extent_map['field_id_name']
     876            new_field_ids = all_field_ids - set(fields_by_id
    872877            fields_by_id.update(dict( 
    873                 (field_id, UNASSIGNED) for field_id in new_fields)) 
     878                (field_id, UNASSIGNED) for field_id in new_field_ids)) 
     879            # Create ephemeral fields for creating new mappings. 
     880            new_fields_by_id = dict(fields_by_id) 
     881            for name, value in fields.iteritems(): 
     882                new_fields_by_id[field_name_id[name]] = value 
     883            if updating_related: 
     884                new_related_entities_by_id = dict( 
     885                    (field_name_id[name], related_entities[name]) 
     886                    for name in related_entities 
     887                    ) 
    874888            # Remove existing index mappings. 
    875889            indices = extent_map['indices'] 
     
    885899                _index_remove(extent_map, index_spec, oid, field_values) 
    886900                ir_append((extent_map, index_spec, relaxed, oid, field_values)) 
    887             # Delete links from this entity to other entities. 
    888             related_entities_by_id = entity_map['related_entities'] 
    889             referrer_extent_id = extent_name_id[extent_name] 
    890             for (referrer_field_id, 
    891                  related_set) in related_entities_by_id.iteritems(): 
    892                 # If a field once existed, but no longer does, there will 
    893                 # still be a related entity set for it in related_entities. 
    894                 # Only process the fields that still exist. 
    895                 if referrer_field_id in all_field_ids: 
    896                     for other_value in related_set: 
    897                         # Remove the link to the other entity. 
    898                         other_extent_id = other_value.extent_id 
    899                         other_oid = other_value.oid 
    900                         link_key = (referrer_extent_id, referrer_field_id) 
    901                         other_extent_map = extent_maps_by_id[other_extent_id] 
    902                         other_entity_map = other_extent_map['entities'][ 
    903                             other_oid] 
    904                         links = other_entity_map['links'] 
    905                         other_links = links[link_key] 
    906                         del other_links[oid] 
    907                         other_entity_map['link_count'] -= 1 
    908                         ld_append((other_entity_map, links, link_key, oid)) 
    909             # Create ephemeral fields for creating new index mappings. 
    910             new_fields = dict(fields_by_id) 
    911             for name, value in fields.iteritems(): 
    912                 new_fields[field_name_id[name]] = value 
     901            if updating_related: 
     902                # Delete links from this entity to other entities. 
     903                related_entities_by_id = entity_map['related_entities'] 
     904                referrer_extent_id = extent_name_id[extent_name] 
     905                new_field_ids = frozenset(new_fields_by_id) 
     906                for (referrer_field_id, 
     907                     related_set) in related_entities_by_id.iteritems(): 
     908                    # If a field once existed, but no longer does, there will 
     909                    # still be a related entity set for it in related_entities. 
     910                    # Only process the fields that still exist. 
     911                    if referrer_field_id in all_field_ids: 
     912##                         for other_value in related_set: 
     913                        # Remove only the links that no longer exist. 
     914                        for other_value in ( 
     915                            related_set 
     916                            - new_related_entities_by_id[referrer_field_id] 
     917                            ): 
     918                            # Remove the link to the other entity. 
     919                            other_extent_id = other_value.extent_id 
     920                            other_oid = other_value.oid 
     921                            link_key = (referrer_extent_id, referrer_field_id) 
     922                            other_extent_map = extent_maps_by_id[ 
     923                                other_extent_id] 
     924                            other_entity_map = other_extent_map['entities'][ 
     925                                other_oid] 
     926                            links = other_entity_map['links'] 
     927                            other_links = links[link_key] 
     928                            del other_links[oid] 
     929                            other_entity_map['link_count'] -= 1 
     930                            ld_append((other_entity_map, links, link_key, oid)) 
    913931            # Create new index mappings. 
    914932            for index_spec in indices.iterkeys(): 
    915                 field_values = tuple(new_fields[field_id] 
     933                field_values = tuple(new_fields_by_id[field_id] 
    916934                                     for field_id in index_spec) 
    917935                # Find out if the index has been relaxed. 
     
    924942                           BTree) 
    925943                ia_append((extent_map, index_spec, oid, field_values)) 
    926             # Update links from this entity to another entity. 
    927             referrer_extent_id = extent_name_id[extent_name] 
    928             for referrer_field_id, other_extent_id, other_oid in new_links: 
    929                 other_extent_map = extent_maps_by_id[other_extent_id] 
    930                 try: 
    931                     other_entity_map = other_extent_map['entities'][other_oid] 
    932                 except KeyError: 
    933                     field_id_name = extent_map['field_id_name'] 
    934                     field_name = field_id_name[referrer_field_id] 
    935                     raise error.EntityDoesNotExist( 
    936                         'Entity referenced in %r does not exist.' 
    937                         % field_name) 
    938                 # Add a link to the other entity. 
    939                 links = other_entity_map['links'] 
    940                 link_key = (referrer_extent_id, referrer_field_id) 
    941                 if link_key not in links:  # XXX Should already be there. 
    942                     links[link_key] = BTree() 
    943                 links[link_key][oid] = None 
    944                 other_entity_map['link_count'] += 1 
    945                 lc_append((other_entity_map, links, link_key, oid)) 
     944            if updating_related: 
     945                # Update links from this entity to another entity. 
     946                referrer_extent_id = extent_name_id[extent_name] 
     947                for referrer_field_id, other_extent_id, other_oid in new_links: 
     948                    other_extent_map = extent_maps_by_id[other_extent_id] 
     949                    try: 
     950                        other_entity_map = other_extent_map['entities'][ 
     951                            other_oid] 
     952                    except KeyError: 
     953                        field_id_name = extent_map['field_id_name'] 
     954                        field_name = field_id_name[referrer_field_id] 
     955                        raise error.EntityDoesNotExist( 
     956                            'Entity referenced in %r does not exist.' 
     957                            % field_name) 
     958                    # Add a link to the other entity. 
     959                    links = other_entity_map['links'] 
     960                    link_key = (referrer_extent_id, referrer_field_id) 
     961                    if link_key not in links:  # XXX Should already be there. 
     962                        mapping = links[link_key] = BTree() 
     963                    else: 
     964                        mapping = links[link_key] 
     965                    if oid not in mapping: 
     966                        # Only add the link if it's not already there. 
     967                        links[link_key][oid] = None 
     968                        other_entity_map['link_count'] += 1 
     969                        lc_append((other_entity_map, links, link_key, oid)) 
    946970            # Update actual fields and related entities. 
    947971            for name, value in fields.iteritems(): 
    948972                fields_by_id[field_name_id[name]] = value 
    949             for name, value in related_entities.iteritems(): 
    950                 related_entities_by_id[field_name_id[name]] = value 
     973            if updating_related: 
     974                for name, value in related_entities.iteritems(): 
     975                    related_entities_by_id[field_name_id[name]] = value 
    951976            # Update revision. 
    952977            if rev is None: