search_storage.py revision 941
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# CDDL HEADER START
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen# The contents of this file are subject to the terms of the
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# Common Development and Distribution License (the "License").
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# You may not use this file except in compliance with the License.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# See the License for the specific language governing permissions
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen# and limitations under the License.
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen# When distributing Covered Code, include this CDDL HEADER in each
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen# If applicable, add the following below this CDDL HEADER, with the
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen# fields enclosed by brackets "[]" replaced with your own identifying
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen# information: Portions Copyright [yyyy] [name of copyright owner]
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen# CDDL HEADER END
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen# Use is subject to license terms.
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainendef consistent_open(data_list, directory, timeout = 1):
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen """Opens all data holders in data_list and ensures that the
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen versions are consistent among all of them.
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen It retries several times in case a race condition between file
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen migration and open is encountered.
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen Note: Do not set timeout to be 0. It will cause an exception to be
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen immediately raised.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen while cur_version == None and missing != True:
538c58fc95200fcc5e91abdda8b912b574a2f968Timo Sirainen # The assignments to cur_version and missing cannot be
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen # placed here. They must be reset prior to breaking out of the
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen # for loop so that the while loop condition will be true. They
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # cannot be placed after the for loop since that path is taken
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # when all files are missing or opened successfully.
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if timeout != None and ((time.time() - start_time) > timeout):
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen raise search_errors.InconsistentIndexException(
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen # All indexes must have the same version and all must
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # either be present or absent for a successful return.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # If one of these conditions is not met, the function
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # tries again until it succeeds or the time spent in
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen # in the function is greater than timeout.
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen f = os.path.join(directory, d.get_file_name())
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen # If we get here, then the current index file
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # is present.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen # Read the version. If this is the first file,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen # set the expected version otherwise check that
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen # the version matches the expected version.
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen # Got inconsistent versions, so close
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen # all files and try again.
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen # If the index file is missing, ensure
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen # that previous files were missing as
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen # well. If not, try again.
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen assert cur_version == None
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen # The index is missing (ie, no files were present).
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen assert cur_version is not None
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen """Base class for all data storage used by the indexer and
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen queryEngine. All members must have a file name and maintain
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen an internal file handle to that file as instructed by external
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen raise RuntimeError("setting an extant file handle, "
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen """Closes the file handle and clears it so that it cannot
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen def _protected_write_dict_file(self, path, version_num, iterable):
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen """Writes the dictionary in the expected format.
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen Note: Only child classes should call this method.
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen file_handle = open(os.path.join(path, self._name), 'wb')
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen file_handle.write(version_string + str(version_num) + "\n")
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen """This method uses the modification time and the file size
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen to (heuristically) determine whether the file backing this
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen storage has changed since it was last read.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen """This uses consistent open to ensure that the version line
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen processing is done consistently and that only a single function
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen actually opens files stored using this class.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen """Class for representing the main dictionary file
7889c9f65e23c83fc31cecf304cab4ab070d6aa1Timo Sirainen # Here is an example of a line from the main dictionary, it is
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen # explained below:
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # %gconf.xml (5,3,65689 => 249,202) (5,3,65690 => 249,202)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # (5,3,65691 => 249,202) (5,3,65692 => 249,202)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # The main dictionary has a more complicated format. Each line begins
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # with a search token (%gconf.xml) followed by a list of mappings. Each
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # mapping takes a token_type, action, and keyvalue tuple ((5,3,65689),
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # (5,3,65690), (5,3,65691), (5,3,65692)) to a list of pkg-stem, version
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # pairs (249,202) in which the token is found in an action with
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # token_type, action, and keyvalues matching the tuple. Further
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # compaction is gained by storing everything but the token as an id
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen # which the other dictionaries can turn into human-readable content.
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen # In short, the definition of a main dictionary entry is:
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # Note: "(", ")", and "=>" actually appear in the file
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen # "[", "]", and "+" are used to specify pattern
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen # token [(token_type_id, action_id, keyval_id => [pkg_stem_id,version_id ]+)]+
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen """This class relies on external methods to write the file.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen Making this empty call to protected_write_dict_file allows the
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen file to be set up correctly with the version number stored
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen IndexStoreBase._protected_write_dict_file(self, path,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen """Return the file handle. Note that doing
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen anything other than sequential reads or writes
075f90abe6b6b12dc72bca21bfce8086b4b190ecTimo Sirainen to or from this file_handle may result in unexpected
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen behavior. In short, don't use seek.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen def __parse_main_dict_line_help(split_chars, unquote_list, line):
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen raise se.EmptyMainDictLine(split_chars, unquote_list)
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen IndexStoreMainDict.__parse_main_dict_line_help(
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen """Parses one line of a main dictionary file.
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen Changes to this function must be paired with changes to
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen write_main_dict_line below.
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen return IndexStoreMainDict.__parse_main_dict_line_help(
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen [True, False, False, True, False, False], line)
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen def __write_main_dict_line_help(file_handle, sep_chars, quote, entries):
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen IndexStoreMainDict.__write_main_dict_line_help(
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen def write_main_dict_line(file_handle, token, lst):
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen """Paired with parse_main_dict_line above. Writes
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen a line in a main dictionary file in the appropriate format.
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen IndexStoreMainDict.__write_main_dict_line_help(file_handle,
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen [True, False, False, True, False, False], (token, lst))
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen def __transform_main_dict_line_help(sep_chars, quote, entries):
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen IndexStoreMainDict.__transform_main_dict_line_help(
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen """Paired with parse_main_dict_line above. Writes
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen a line in a main dictionary file in the appropriate format.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen tmp = IndexStoreMainDict.__transform_main_dict_line_help(
659fe5d24825b160cae512538088020d97a60239Timo Sirainen [True, False, False, True, False, False], (token, lst))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen def count_entries_removed_during_partial_indexing(self):
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen """Returns the number of entries removed during a second phase
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen # This returns 0 because this class is not responsible for
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen # storing anything in memory.
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainen """Moves the existing file with self._name in directory
51920d00fa50edf7b2e9b1019288d64b7abee7f3Timo Sirainen use_dir to a new file named self._name + suffix in directory
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen use_dir. If it has done this previously, it removes the old
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen file it moved. It also opens the newly moved file and uses
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen that as the file for its file handle.
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen new_path = os.path.join(use_dir, self._name + suffix)
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen os.remove(os.path.join(use_dir, self._old_suffix))
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen """Used when both a list and a dictionary are needed to
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen store the information. Used for bidirectional lookup when
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen one item is an int (an id) and the other is not (an entity). It
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen maintains a list of empty spots in the list so that adding entities
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen can take advantage of unused space. It encodes empty space as a blank
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen line in the file format and '' in the internal list.
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen def __init__(self, file_name, build_function=None):
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen """Adds an entity consistently to the list and dictionary
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen allowing bidirectional lookup.
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen """deletes in_id from the list and the dictionary """
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen """deletes the entity from the list and the dictionary """
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen """returns the id of entity """
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen """Adds entity if it's not previously stored and returns the
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen id for entity.
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen # This code purposefully reimplements add_entity
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen # code. Replacing the function calls to has_entity, add_entity,
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen # and get_id with direct access to the data structure gave a
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen # speed up of a factor of 4. Because this is a very hot path,
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen # the tradeoff seemed appropriate.
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen """return the entity in_id maps to """
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen """check if entity is in storage """
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen """Check if the structure has any empty elements which
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen can be filled with data.
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen """returns the next id which maps to no element """
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen """Passes self._list to the parent class to write to a file.
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen IndexStoreBase._protected_write_dict_file(self, path,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen """Reads in a dictionary previously stored using the above
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen # A blank line means that id can be reused.
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen def count_entries_removed_during_partial_indexing(self):
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen """Returns the number of entries removed during a second phase
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen """Class used when only entity -> id lookup is needed
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen """Reads in a dictionary stored in line number -> entity
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen for line_cnt, line in enumerate(self._file_handle):
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen def matching_read_dict_file(self, in_set, update=False):
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen """If it's necessary to reread the file, it rereads the
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen file. It matches the line it reads against the contents of
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen in_set. If a match is found, the entry on the line is stored
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen for later use, otherwise the line is skipped. When all items
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen in in_set have been matched, the method is done and returns.
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen # skip the version line
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen def count_entries_removed_during_partial_indexing(self):
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen """Returns the number of entries removed during a second phase
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen """Dictionary which allows dynamic update of its storage
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen """Reads in a dictionary stored in with an entity
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen and its number on each line.
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen def open_out_file(self, use_dir, version_num):
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen """Opens the output file for this class and prepares it
91d4c7b37580b031ed7b0154ae10c643521803f3Timo Sirainen to be written via write_entity.
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen self._file_handle = open(os.path.join(use_dir, self._name),
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen """Writes the entity out to the file with my_id """
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen self._file_handle.write(self.__quote(str(entity)) + " " +
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen """ Generates an iterable list of string representations of
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen the dictionary that the parent's protected_write_dict_file
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen function can call.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen IndexStoreBase._protected_write_dict_file(self, path,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen def count_entries_removed_during_partial_indexing(self):
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen """Returns the number of entries removed during a second phase
d12f05c7c391786d0d9795ec3aa4377280bbfaeaTimo Sirainen """Set the has value."""
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen """Calculate the hash value of the sorted members of vals."""
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen """Write self.hash_val out to a line in a file """
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen IndexStoreBase._protected_write_dict_file(self, path,
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen """Process a dictionary file written using the above method
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen for res, line in enumerate(self._file_handle):
c3248869ddd406a7a46b8c05633f0cccc72fcb77Timo Sirainen """Check the hash value of vals against the value stored
c3248869ddd406a7a46b8c05633f0cccc72fcb77Timo Sirainen in the file for this object."""
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen def count_entries_removed_during_partial_indexing(self):
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen """Returns the number of entries removed during a second phase
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen of indexing."""
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen """Used when only set membership is desired.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen This is currently designed for exclusive use
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen with storage of fmri.PkgFmris. However, that impact
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen is only seen in the read_and_discard_matching_from_argument
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen """Remove entity purposfully assumes that entity is
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen already in the set to be removed. This is useful for
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen error checking and debugging.
1dec807061d7d428dba5c5a92cd2a5ff843a2039Timo Sirainen """Write each member of the set out to a line in a file """
1dec807061d7d428dba5c5a92cd2a5ff843a2039Timo Sirainen IndexStoreBase._protected_write_dict_file(self, path,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen """Process a dictionary file written using the above method
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen def read_and_discard_matching_from_argument(self, fmri_set):
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen """Reads the file and removes all frmis in the file
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen from fmri_set.
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen def count_entries_removed_during_partial_indexing(self):
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen """Returns the number of entries removed during a second phase
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen of indexing."""