|
2 | 2 | import os
|
3 | 3 | import threading
|
4 | 4 | import warnings
|
| 5 | +import weakref |
5 | 6 | import zlib
|
6 | 7 | from collections import Iterable, Sequence, Sized
|
7 | 8 | from functools import reduce
|
@@ -316,6 +317,12 @@ def from_table(cls, domain, source, row_indices=...):
|
316 | 317 | :rtype: Orange.data.Table
|
317 | 318 | """
|
318 | 319 |
|
| 320 | + def valid_refs(weakrefs): |
| 321 | + for r in weakrefs: |
| 322 | + if r() is None: |
| 323 | + return False |
| 324 | + return True |
| 325 | + |
319 | 326 | def get_columns(row_indices, src_cols, n_rows, dtype=np.float64,
|
320 | 327 | is_sparse=False, variables=[]):
|
321 | 328 | if not len(src_cols):
|
@@ -356,10 +363,13 @@ def get_columns(row_indices, src_cols, n_rows, dtype=np.float64,
|
356 | 363 | a[:, i] = variables[i].Unknown
|
357 | 364 | elif not isinstance(col, Integral):
|
358 | 365 | if isinstance(col, SharedComputeValue):
|
359 |
| - if (id(col.compute_shared), id(source)) not in shared_cache: |
360 |
| - shared_cache[id(col.compute_shared), id(source)] = \ |
361 |
| - col.compute_shared(source) |
362 |
| - shared = shared_cache[id(col.compute_shared), id(source)] |
| 366 | + shared, weakrefs = shared_cache.get((id(col.compute_shared), id(source)), |
| 367 | + (None, None)) |
| 368 | + if shared is None or not valid_refs(weakrefs): |
| 369 | + shared, _ = shared_cache[(id(col.compute_shared), id(source))] = \ |
| 370 | + col.compute_shared(source), \ |
| 371 | + (weakref.ref(col.compute_shared), weakref.ref(source)) |
| 372 | + |
363 | 373 | if row_indices is not ...:
|
364 | 374 | a[:, i] = match_density(
|
365 | 375 | col(source, shared_data=shared)[row_indices])
|
@@ -389,8 +399,9 @@ def get_columns(row_indices, src_cols, n_rows, dtype=np.float64,
|
389 | 399 | if new_cache:
|
390 | 400 | _thread_local.conversion_cache = {}
|
391 | 401 | else:
|
392 |
| - cached = _thread_local.conversion_cache.get((id(domain), id(source))) |
393 |
| - if cached: |
| 402 | + cached, weakrefs = \ |
| 403 | + _thread_local.conversion_cache.get((id(domain), id(source)), (None, None)) |
| 404 | + if cached and valid_refs(weakrefs): |
394 | 405 | return cached
|
395 | 406 | if domain is source.domain:
|
396 | 407 | table = cls.from_table_rows(source, row_indices)
|
@@ -443,7 +454,8 @@ def get_columns(row_indices, src_cols, n_rows, dtype=np.float64,
|
443 | 454 | else:
|
444 | 455 | cls._init_ids(self)
|
445 | 456 | self.attributes = getattr(source, 'attributes', {})
|
446 |
| - _thread_local.conversion_cache[(id(domain), id(source))] = self |
| 457 | + _thread_local.conversion_cache[(id(domain), id(source))] = \ |
| 458 | + self, (weakref.ref(domain), weakref.ref(source)) |
447 | 459 | return self
|
448 | 460 | finally:
|
449 | 461 | if new_cache:
|
|
0 commit comments