13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
18
"""B+Tree indices"""
180
181
combine mem with the first and second indexes, creating a new one of
181
182
size 4x. On the fifth create a single new one, etc.
184
if self._combine_backing_indices:
185
(new_backing_file, size,
186
backing_pos) = self._spill_mem_keys_and_combine()
188
new_backing_file, size = self._spill_mem_keys_without_combining()
189
dir_path, base_name = osutils.split(new_backing_file.name)
190
# Note: The transport here isn't strictly needed, because we will use
191
# direct access to the new_backing._file object
192
new_backing = BTreeGraphIndex(get_transport(dir_path),
194
# GC will clean up the file
195
new_backing._file = new_backing_file
196
if self._combine_backing_indices:
197
if len(self._backing_indices) == backing_pos:
198
self._backing_indices.append(None)
199
self._backing_indices[backing_pos] = new_backing
200
for backing_pos in range(backing_pos):
201
self._backing_indices[backing_pos] = None
203
self._backing_indices.append(new_backing)
206
self._nodes_by_key = None
208
def _spill_mem_keys_without_combining(self):
209
return self._write_nodes(self._iter_mem_nodes(), allow_optimize=False)
211
def _spill_mem_keys_and_combine(self):
183
212
iterators_to_combine = [self._iter_mem_nodes()]
185
214
for pos, backing in enumerate(self._backing_indices):
191
220
new_backing_file, size = \
192
221
self._write_nodes(self._iter_smallest(iterators_to_combine),
193
222
allow_optimize=False)
194
dir_path, base_name = osutils.split(new_backing_file.name)
195
# Note: The transport here isn't strictly needed, because we will use
196
# direct access to the new_backing._file object
197
new_backing = BTreeGraphIndex(get_transport(dir_path),
199
# GC will clean up the file
200
new_backing._file = new_backing_file
201
if len(self._backing_indices) == backing_pos:
202
self._backing_indices.append(None)
203
self._backing_indices[backing_pos] = new_backing
204
for pos in range(backing_pos):
205
self._backing_indices[pos] = None
208
self._nodes_by_key = None
223
return new_backing_file, size, backing_pos
210
225
def add_nodes(self, nodes):
211
226
"""Add nodes to the index.
627
642
# Default max size is 100,000 leave values
628
643
self._leaf_value_cache = None # lru_cache.LRUCache(100*1000)
629
644
self._leaf_node_cache = lru_cache.LRUCache(_NODE_CACHE_SIZE)
630
self._internal_node_cache = lru_cache.LRUCache()
645
# We could limit this, but even a 300k record btree has only 3k leaf
646
# nodes, and only 20 internal nodes. So the default of 100 nodes in an
647
# LRU would mean we always cache everything anyway, no need to pay the
649
self._internal_node_cache = fifo_cache.FIFOCache(100)
631
650
self._key_count = None
632
651
self._row_lengths = None
633
652
self._row_offsets = None # Start of each row, [-1] is the end