'Update this MultiLangZone with the buffer data.
@param buf {CitadelBuffer} the buffer whose data is being added
to the database.
@param scan_tree {ciElementTree} the CIX scan data. Might be None
if there was an early scanning failure.
@param scan_time {timestamp} the time of the scan, typically the
mtime of the file
@param scan_error {str} an error string if scanning failed, or
None if it was succesful.
@param skip_scan_time_check {boolean} (default False) is a
boolean indicating if the buffer data should be updated even
if `scan_time` is <= that in the database.'

def update_buf_data(self, buf, scan_tree, scan_time, scan_error, skip_scan_time_check=False):

    self._acquire_lock()
    try:
        (dir, base) = split(buf.path)
        res_index = self.load_index(dir, 'res_index', {})
        res_index_has_changed = False
        blob_index = self.load_index(dir, 'blob_index', {})
        blob_index_has_changed = False
        is_hits_from_lpath_lang = (self.lang in self.db.import_everything_langs)
        if is_hits_from_lpath_lang:
            toplevelname_index = self.load_index(dir, 'toplevelname_index', {})
            toplevelname_index_has_changed = False
        try:
            (old_scan_time, old_scan_error, old_res_data) = res_index[base]
        except KeyError:
            (old_scan_time, old_scan_error, old_res_data) = (None, None, {})
        else:
            if ((not skip_scan_time_check) and (scan_time is not None) and (scan_time <= old_scan_time)):
                log.debug("skipping    db    update    for    '%s':    %s    <    %s    and    no    'skip_scan_time_check'    option", base, scan_time, old_scan_time)
                return
        log.debug("update    from    %s    buf    '%s'", buf.lang, buf.path)
        new_res_data = {}
        new_blob_from_lang_and_blobname = {}
        if scan_tree:
            for blob in scan_tree[0]:
                lang = blob.get('lang')
                blobname = blob.get('name')
                new_blob_from_lang_and_blobname[(lang, blobname)] = blob
                tfifb = new_res_data.setdefault(lang, {})
                toplevelnames_from_ilk = tfifb.setdefault(blobname, {})
                for (toplevelname, elem) in blob.names.iteritems():
                    ilk = (elem.get('ilk') or elem.tag)
                    if (ilk not in toplevelnames_from_ilk):
                        toplevelnames_from_ilk[ilk] = set([toplevelname])
                    else:
                        toplevelnames_from_ilk[ilk].add(toplevelname)
                    if ((ilk == 'namespace') and (lang == 'PHP')):
                        for (childname, childelem) in elem.names.iteritems():
                            child_ilk = (childelem.get('ilk') or childelem.tag)
                            child_fqn = ('%s\\%s' % (toplevelname, childname))
                            if (child_ilk not in toplevelnames_from_ilk):
                                toplevelnames_from_ilk[child_ilk] = set([child_fqn])
                            else:
                                toplevelnames_from_ilk[child_ilk].add(child_fqn)
        if scan_error:
            if ((scan_time != old_scan_time) or (scan_error != old_scan_error)):
                res_index[base] = (scan_time, scan_error, old_res_data)
                res_index_has_changed = True
        else:
            if ((scan_time != old_scan_time) or (scan_error != old_scan_error) or (new_res_data != old_res_data)):
                res_index[base] = (scan_time, scan_error, new_res_data)
                res_index_has_changed = True
            if is_hits_from_lpath_lang:
                if (new_res_data != old_res_data):
                    toplevelname_index.update(base, old_res_data, new_res_data)
                    toplevelname_index_has_changed = True
            dbfile_changes = []
            for ((lang, blobname), blob) in new_blob_from_lang_and_blobname.items():
                try:
                    old_res_data[lang][blobname]
                except KeyError:
                    dbfile_changes.append(('add', lang, blobname, blob))
                else:
                    dbfile_changes.append(('update', lang, blobname, blob))
            for (lang, old_tfifb) in old_res_data.items():
                for blobname in old_tfifb:
                    try:
                        new_res_data[lang][blobname]
                    except KeyError:
                        dbfile_changes.append(('remove', lang, blobname, None))
            dhash = self.dhash_from_dir(dir)
            for (action, lang, blobname, blob) in dbfile_changes:
                if (action == 'add'):
                    dbfile = self.db.bhash_from_blob_info(buf.path, lang, blobname)
                    blob_index.setdefault(lang, {})[blobname] = dbfile
                    blob_index_has_changed = True
                    dbdir = join(self.base_dir, dhash)
                    if (not exists(dbdir)):
                        self._mk_dbdir(dbdir, dir)
                    log.debug("fs-write:    %s|%s    blob    '%s/%s'", self.lang, lang, dhash, dbfile)
                    if (blob.get('src') is None):
                        blob.set('src', buf.path)
                    ET.ElementTree(blob).write(join(dbdir, (dbfile + '.blob')))
                elif (action == 'remove'):
                    dbfile = blob_index[lang][blobname]
                    del blob_index[lang][blobname]
                    blob_index_has_changed = True
                    log.debug("fs-write:    remove    %s|%s    blob    '%s/%s'", self.lang, lang, dhash, dbfile)
                    try:
                        os.remove(join(self.base_dir, dhash, (dbfile + '.blob')))
                    except EnvironmentError as ex:
                        self.db.corruption('MultiLangZone.update_buf_data', ("could    not    remove    dbfile    for    '%s'    blob:    %s" % (blobname, ex)), 'ignore')
                elif (action == 'update'):
                    s = StringIO()
                    if (blob.get('src') is None):
                        blob.set('src', buf.path)
                    ET.ElementTree(blob).write(s)
                    new_dbfile_content = s.getvalue()
                    dbfile = blob_index[lang][blobname]
                    dbpath = join(self.base_dir, dhash, (dbfile + '.blob'))
                    try:
                        fin = open(dbpath, 'r')
                    except (OSError, IOError) as ex:
                        old_dbfile_content = None
                    else:
                        try:
                            old_dbfile_content = fin.read()
                        finally:
                            fin.close()
                    if (new_dbfile_content != old_dbfile_content):
                        if (not exists(dirname(dbpath))):
                            self._mk_dbdir(dirname(dbpath), dir)
                        log.debug("fs-write:    %s|%s    blob    '%s/%s'", self.lang, lang, dhash, dbfile)
                        fout = open(dbpath, 'w')
                        try:
                            fout.write(new_dbfile_content)
                        finally:
                            fout.close()
        if res_index_has_changed:
            self.changed_index(dir, 'res_index')
        if blob_index_has_changed:
            self.changed_index(dir, 'blob_index')
        if (is_hits_from_lpath_lang and toplevelname_index_has_changed):
            self.changed_index(dir, 'toplevelname_index')
    finally:
        self._release_lock()
