10046 client always rereads dictionaries
authorBrock Pytlik <bpytlik@sun.com>
Thu, 16 Jul 2009 14:21:08 -0700
changeset 1230 4bc74e5d6c3d
parent 1229 4e775e2baecd
child 1231 f7b99e8118d2
10046 client always rereads dictionaries
src/modules/client/query_parser.py
src/modules/search_storage.py
src/tests/cli/t_api_search.py
--- a/src/modules/client/query_parser.py	Thu Jul 16 12:44:34 2009 -0500
+++ b/src/modules/client/query_parser.py	Thu Jul 16 14:21:08 2009 -0700
@@ -100,7 +100,9 @@
             ss.IndexStoreSet(ss.FAST_ADD)
         qp.TermQuery._global_data_dict["fast_remove"] = \
             ss.IndexStoreSet(ss.FAST_REMOVE)
-        
+        qp.TermQuery._global_data_dict["fmri_hash"] = \
+            ss.IndexStoreSetHash(ss.FULL_FMRI_HASH_FILE)
+
         def __init__(self, term):
                 qp.TermQuery.__init__(self, term)
                 self._impl_fmri_to_path = None
@@ -131,12 +133,6 @@
                 TermQuery.client_dict_lock.acquire()
                 try:
                         try:
-                                # Temporarily add the fmri_hash storage object
-                                # to the shared dictionary structure so that its
-                                # file will be opened at the same time as the
-                                # other storage objects.
-                                qp.TermQuery._global_data_dict["fmri_hash"] = \
-                                    ss.IndexStoreSetHash(ss.FULL_FMRI_HASH_FILE)
                                 qp.TermQuery.set_info(self, dir_path,
                                     fmri_to_manifest_path_func, case_sensitive)
                                 # Take local copies of the client-only
@@ -155,9 +151,6 @@
                                 # search will be used.
                                 TopQuery.use_slow = True
                 finally:
-                        # Remove the fmri_hash object from the shared data
-                        # structure since it does not work when shared.
-                        del qp.TermQuery._global_data_dict["fmri_hash"]
                         TermQuery.client_dict_lock.release()
                 
         def search(self, restriction, fmris, manifest_func, excludes):
--- a/src/modules/search_storage.py	Thu Jul 16 12:44:34 2009 -0500
+++ b/src/modules/search_storage.py	Thu Jul 16 14:21:08 2009 -0700
@@ -142,6 +142,8 @@
                 self._file_path = None
                 self._size = None
                 self._mtime = None
+                self._inode = None
+                self._have_read = False
 
         def get_file_name(self):
                 return self._name
@@ -153,6 +155,11 @@
                 else:
                         self._file_handle = f_handle
                         self._file_path = f_path
+                        if self._mtime is None: 
+                                stat_info = os.stat(self._file_path)
+                                self._mtime = stat_info.st_mtime
+                                self._size = stat_info.st_size
+                                self._inode = stat_info.st_ino
 
         def get_file_path(self):
                 return self._file_path
@@ -164,6 +171,7 @@
                 """Closes the file handle and clears it so that it cannot
                 be reused.
                 """
+
                 if self._file_handle:
                         self._file_handle.close()
                         self._file_handle = None
@@ -185,12 +193,14 @@
                 storage has changed since it was last read.
                 """
                 stat_info = os.stat(self._file_path)
-                if self._mtime != stat_info.st_mtime or \
+                if self._inode != stat_info.st_ino or \
+                    self._mtime != stat_info.st_mtime or \
                     self._size != stat_info.st_size:
-                        self._mtime = stat_info.st_mtime
-                        self._size = stat_info.st_size
                         return True
-                return False
+                return not self._have_read
+
+        def read_dict_file(self):
+                self._have_read = True
 
         def open(self, directory):
                 """This uses consistent open to ensure that the version line
@@ -542,19 +552,19 @@
                 call
                 """
                 assert self._file_handle
-                if self.should_reread():
-                        self._dict.clear()
-                        self._list = []
-                        for i, line in enumerate(self._file_handle):
-                                # A blank line means that id can be reused.
-                                tmp = self._build_func(line.rstrip('\n'))
-                                if line == '\n':
-                                        self._list_of_empties.append(i)
-                                else:
-                                        self._dict[tmp] = i
-                                self._list.append(tmp)
-                                self._line_cnt = i + 1
-                                self._next_id = i + 1
+                self._dict.clear()
+                self._list = []
+                for i, line in enumerate(self._file_handle):
+                        # A blank line means that id can be reused.
+                        tmp = self._build_func(line.rstrip("\n"))
+                        if line == "\n":
+                                self._list_of_empties.append(i)
+                        else:
+                                self._dict[tmp] = i
+                        self._list.append(tmp)
+                        self._line_cnt = i + 1
+                        self._next_id = i + 1
+                IndexStoreBase.read_dict_file(self)
                 return self._line_cnt
 
         def count_entries_removed_during_partial_indexing(self):
@@ -585,11 +595,11 @@
                 """Reads in a dictionary stored in line number -> entity
                 format
                 """
-                if self.should_reread():
-                        self._dict.clear()
-                        for line_cnt, line in enumerate(self._file_handle):
-                                line = line.rstrip('\n')
-                                self._dict[line_cnt] = line
+                self._dict.clear()
+                for line_cnt, line in enumerate(self._file_handle):
+                        line = line.rstrip("\n")
+                        self._dict[line_cnt] = line
+                IndexStoreBase.read_dict_file(self)
 
         def matching_read_dict_file(self, in_set, update=False):
                 """If it's necessary to reread the file, it rereads the
@@ -602,7 +612,7 @@
                 is left in place and any new information is added to it.
                 """
 
-                if update or self.should_reread():
+                if update or not self._have_read:
                         if not update:
                                 self._dict.clear()
                         match_cnt = 0
@@ -662,13 +672,13 @@
                 """Reads in a dictionary stored in with an entity
                 and its number on each line.
                 """
-                if self.should_reread():
-                        self._dict.clear()
-                        for line in self._file_handle:
-                                res = line.split(" ")
-                                token = self.__unquote(res[0])
-                                offset = int(res[1])
-                                self._dict[token] = offset
+                self._dict.clear()
+                for line in self._file_handle:
+                        res = line.split(" ")
+                        token = self.__unquote(res[0])
+                        offset = int(res[1])
+                        self._dict[token] = offset
+                IndexStoreBase.read_dict_file(self)
 
         def open_out_file(self, use_dir, version_num):
                 """Opens the output file for this class and prepares it
@@ -702,7 +712,7 @@
         def __init__(self, file_name):
                 IndexStoreBase.__init__(self, file_name)
                 self.hash_val = sha.new().hexdigest()
-                
+
         def set_hash(self, vals):
                 """Set the has value."""
                 self.hash_val = self.calc_hash(vals) 
@@ -724,19 +734,20 @@
         def read_dict_file(self):
                 """Process a dictionary file written using the above method
                 """
-                if self.should_reread():
-                        sp = self._file_handle.tell()
-                        res = 0
-                        for res, line in enumerate(self._file_handle):
-                                assert res < 1
-                                self.hash_val = line.rstrip()
-                        self._file_handle.seek(sp)
-                        return res
+                sp = self._file_handle.tell()
+                res = 0
+                for res, line in enumerate(self._file_handle):
+                        assert res < 1
+                        self.hash_val = line.rstrip()
+                self._file_handle.seek(sp)
+                IndexStoreBase.read_dict_file(self)
+                return res
 
         def check_against_file(self, vals):
                 """Check the hash value of vals against the value stored
                 in the file for this object."""
-                self.read_dict_file()
+                if not self._have_read:
+                        self.read_dict_file()
                 incoming_hash = self.calc_hash(vals)
                 if self.hash_val != incoming_hash:
                         raise search_errors.IncorrectIndexFileHash(
@@ -784,13 +795,13 @@
                 """
                 assert self._file_handle
                 res = 0
-                if self.should_reread():
-                        self._set.clear()
-                        for i, line in enumerate(self._file_handle):
-                                line = line.rstrip('\n')
-                                assert i == len(self._set)
-                                self.add_entity(line)
-                                res = i + 1
+                self._set.clear()
+                for i, line in enumerate(self._file_handle):
+                        line = line.rstrip("\n")
+                        assert i == len(self._set)
+                        self.add_entity(line)
+                        res = i + 1
+                IndexStoreBase.read_dict_file(self)
                 return res
 
         def read_and_discard_matching_from_argument(self, fmri_set):
@@ -887,10 +898,10 @@
                 information in a dictionary."""
 
                 assert self._file_handle
-                if self.should_reread():
-                        for l in self._file_handle:
-                                fmris, offs = l.split("!")
-                                self._dict[fmris] = offs
+                for l in self._file_handle:
+                        fmris, offs = l.split("!")
+                        self._dict[fmris] = offs
+                IndexStoreBase.read_dict_file(self)
 
         @staticmethod
         def de_delta(offs):
--- a/src/tests/cli/t_api_search.py	Thu Jul 16 12:44:34 2009 -0500
+++ b/src/tests/cli/t_api_search.py	Thu Jul 16 14:21:08 2009 -0700
@@ -27,14 +27,15 @@
 if __name__ == "__main__":
 	testutils.setup_environment("../../../proto")
 
-import unittest
+import copy
+import difflib
 import os
-import sys
-import copy
 import re
 import shutil
-import difflib
+import sys
+import tempfile
 import time
+import unittest
 
 import pkg.client.api as api
 import pkg.client.api_errors as api_errors
@@ -991,11 +992,14 @@
 
         @staticmethod
         def _overwrite_hash(ffh_path):
-                fh = open(ffh_path, "r+")
+                fd, tmp = tempfile.mkstemp()
+                portable.copyfile(ffh_path, tmp)
+                fh = open(tmp, "r+")
                 fh.seek(0)
                 fh.seek(20)
                 fh.write("*")
                 fh.close()
+                portable.rename(tmp, ffh_path)
 
         def _check_no_index(self):
                 ind_dir, ind_dir_tmp = self._get_index_dirs()
@@ -1201,10 +1205,10 @@
                         api_obj.reset()
                         self._search_op(api_obj, False, "example_pkg",
                             self.res_local_pkg)
-                        
+
                 ffh = ss.IndexStoreSetHash(ss.FULL_FMRI_HASH_FILE)
                 ffh_path = os.path.join(index_dir, ffh.get_file_name())
-                dest_path = ffh_path + "TMP"
+                dest_fh, dest_path = tempfile.mkstemp()
                 shutil.copy(ffh_path, dest_path)
                 self._overwrite_hash(ffh_path)
                 self.assertRaises(api_errors.IncorrectIndexFileHash,