from BTrees.IOBTree import IOBTree
from random import randint
def updateMetadata(self, object, uid):
    """ Given an object and a uid, update the column data for the
    uid with the object data iff the object has changed """
    data = self.data
    index = self.uids.get(uid, None)
    newDataRecord = self.recordify(object)

    if index is None:
        if type(data) is IOBTree:
            # New style, get random id

            index=getattr(self, '_v_nextid', 0)
            if index % 4000 == 0:
                index = randint(-2000000000, 2000000000)
            while not data.insert(index, newDataRecord):
                index = randint(-2000000000, 2000000000)

            # We want ids to be somewhat random, but there are
            # advantages for having some ids generated
            # sequentially when many catalog updates are done at
            # once, such as when reindexing or bulk indexing.
            # We allocate ids sequentially using a volatile base,
            # so different threads get different bases. This
            # further reduces conflict and reduces churn in
            # here and it result sets when bulk indexing.
            self._v_nextid=index+1
        else:
            if data:
                # find the next available unique id
                index = data.keys()[-1] + 1
            else:
                index=0
            # meta_data is stored as a tuple for efficiency
            data[index] = newDataRecord
    else:
        #if True or data.get(index, 0) != newDataRecord:
        data[index] = newDataRecord
    return index
from Products.ZCatalog.Catalog import Catalog
Catalog.updateMetadata = updateMetadata
