deltacat 1.1.0__py3-none-any.whl → 1.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
deltacat/__init__.py CHANGED
@@ -44,7 +44,7 @@ from deltacat.types.tables import TableWriteMode
44
44
 
45
45
  deltacat.logs.configure_deltacat_logger(logging.getLogger(__name__))
46
46
 
47
- __version__ = "1.1.0"
47
+ __version__ = "1.1.1"
48
48
 
49
49
 
50
50
  __all__ = [
@@ -20,6 +20,7 @@ from deltacat.compute.compactor_v2.constants import (
20
20
  AVERAGE_RECORD_SIZE_BYTES,
21
21
  TASK_MAX_PARALLELISM,
22
22
  DROP_DUPLICATES,
23
+ TOTAL_MEMORY_BUFFER_PERCENTAGE,
23
24
  )
24
25
  from deltacat.constants import PYARROW_INFLATION_MULTIPLIER
25
26
  from deltacat.compute.compactor.utils.sort_key import validate_sort_keys
@@ -85,12 +86,17 @@ class CompactPartitionParams(dict):
85
86
  result.average_record_size_bytes = params.get(
86
87
  "average_record_size_bytes", AVERAGE_RECORD_SIZE_BYTES
87
88
  )
89
+ result.total_memory_buffer_percentage = params.get(
90
+ "total_memory_buffer_percentage", TOTAL_MEMORY_BUFFER_PERCENTAGE
91
+ )
88
92
  result.hash_group_count = params.get(
89
93
  "hash_group_count", result.hash_bucket_count
90
94
  )
91
95
  result.drop_duplicates = params.get("drop_duplicates", DROP_DUPLICATES)
92
96
  result.ray_custom_resources = params.get("ray_custom_resources")
93
97
 
98
+ result.memory_logs_enabled = params.get("memory_logs_enabled", False)
99
+
94
100
  result.metrics_config = params.get("metrics_config")
95
101
 
96
102
  if not importlib.util.find_spec("memray"):
@@ -190,6 +196,16 @@ class CompactPartitionParams(dict):
190
196
  def average_record_size_bytes(self, average_record_size_bytes: float) -> None:
191
197
  self["average_record_size_bytes"] = average_record_size_bytes
192
198
 
199
+ @property
200
+ def total_memory_buffer_percentage(self) -> int:
201
+ return self["total_memory_buffer_percentage"]
202
+
203
+ @total_memory_buffer_percentage.setter
204
+ def total_memory_buffer_percentage(
205
+ self, total_memory_buffer_percentage: int
206
+ ) -> None:
207
+ self["total_memory_buffer_percentage"] = total_memory_buffer_percentage
208
+
193
209
  @property
194
210
  def min_files_in_batch(self) -> float:
195
211
  return self["min_files_in_batch"]
@@ -355,6 +371,14 @@ class CompactPartitionParams(dict):
355
371
  def sort_keys(self, keys: List[SortKey]) -> None:
356
372
  self["sort_keys"] = keys
357
373
 
374
+ @property
375
+ def memory_logs_enabled(self) -> bool:
376
+ return self.get("memory_logs_enabled")
377
+
378
+ @memory_logs_enabled.setter
379
+ def memory_logs_enabled(self, value: bool) -> None:
380
+ self["memory_logs_enabled"] = value
381
+
358
382
  @property
359
383
  def metrics_config(self) -> Optional[MetricsConfig]:
360
384
  return self.get("metrics_config")
@@ -84,6 +84,13 @@ class CompactionSessionAuditInfo(dict):
84
84
  """
85
85
  return self.get("recordsDeduped")
86
86
 
87
+ @property
88
+ def records_deleted(self) -> int:
89
+ """
90
+ The total count of deleted records in a compaction session if delete deltas are present.
91
+ """
92
+ return self.get("recordsDeleted")
93
+
87
94
  @property
88
95
  def input_size_bytes(self) -> float:
89
96
  """
@@ -461,6 +468,10 @@ class CompactionSessionAuditInfo(dict):
461
468
  self["recordsDeduped"] = records_deduped
462
469
  return self
463
470
 
471
+ def set_records_deleted(self, records_deleted: int) -> CompactionSessionAuditInfo:
472
+ self["recordsDeleted"] = records_deleted
473
+ return self
474
+
464
475
  def set_input_size_bytes(
465
476
  self, input_size_bytes: float
466
477
  ) -> CompactionSessionAuditInfo:
@@ -62,6 +62,7 @@ from deltacat.utils.resources import (
62
62
  from deltacat.compute.compactor_v2.utils.task_options import (
63
63
  hash_bucket_resource_options_provider,
64
64
  merge_resource_options_provider,
65
+ local_merge_resource_options_provider,
65
66
  )
66
67
  from deltacat.compute.compactor.model.compactor_version import CompactorVersion
67
68
 
@@ -258,8 +259,10 @@ def _execute_compaction(
258
259
  resource_amount_provider=hash_bucket_resource_options_provider,
259
260
  previous_inflation=params.previous_inflation,
260
261
  average_record_size_bytes=params.average_record_size_bytes,
262
+ total_memory_buffer_percentage=params.total_memory_buffer_percentage,
261
263
  primary_keys=params.primary_keys,
262
264
  ray_custom_resources=params.ray_custom_resources,
265
+ memory_logs_enabled=params.memory_logs_enabled,
263
266
  )
264
267
 
265
268
  total_input_records_count = np.int64(0)
@@ -275,7 +278,29 @@ def _execute_compaction(
275
278
  delete_strategy,
276
279
  delete_file_envelopes,
277
280
  )
278
- local_merge_result = ray.get(mg.merge.remote(local_merge_input))
281
+ estimated_da_bytes = (
282
+ compaction_audit.estimated_in_memory_size_bytes_during_discovery
283
+ )
284
+ estimated_num_records = sum(
285
+ [
286
+ entry.meta.record_count
287
+ for delta in uniform_deltas
288
+ for entry in delta.manifest.entries
289
+ ]
290
+ )
291
+ local_merge_options = local_merge_resource_options_provider(
292
+ estimated_da_size=estimated_da_bytes,
293
+ estimated_num_rows=estimated_num_records,
294
+ total_memory_buffer_percentage=params.total_memory_buffer_percentage,
295
+ round_completion_info=round_completion_info,
296
+ compacted_delta_manifest=previous_compacted_delta_manifest,
297
+ ray_custom_resources=params.ray_custom_resources,
298
+ primary_keys=params.primary_keys,
299
+ memory_logs_enabled=params.memory_logs_enabled,
300
+ )
301
+ local_merge_result = ray.get(
302
+ mg.merge.options(**local_merge_options).remote(local_merge_input)
303
+ )
279
304
  total_input_records_count += local_merge_result.input_record_count
280
305
  merge_results = [local_merge_result]
281
306
  merge_invoke_end = time.monotonic()
@@ -296,6 +321,7 @@ def _execute_compaction(
296
321
  object_store=params.object_store,
297
322
  deltacat_storage=params.deltacat_storage,
298
323
  deltacat_storage_kwargs=params.deltacat_storage_kwargs,
324
+ memory_logs_enabled=params.memory_logs_enabled,
299
325
  )
300
326
  }
301
327
 
@@ -382,12 +408,14 @@ def _execute_compaction(
382
408
  num_hash_groups=params.hash_group_count,
383
409
  hash_group_size_bytes=all_hash_group_idx_to_size_bytes,
384
410
  hash_group_num_rows=all_hash_group_idx_to_num_rows,
411
+ total_memory_buffer_percentage=params.total_memory_buffer_percentage,
385
412
  round_completion_info=round_completion_info,
386
413
  compacted_delta_manifest=previous_compacted_delta_manifest,
387
414
  primary_keys=params.primary_keys,
388
415
  deltacat_storage=params.deltacat_storage,
389
416
  deltacat_storage_kwargs=params.deltacat_storage_kwargs,
390
417
  ray_custom_resources=params.ray_custom_resources,
418
+ memory_logs_enabled=params.memory_logs_enabled,
391
419
  )
392
420
 
393
421
  def merge_input_provider(index, item):
@@ -417,6 +445,7 @@ def _execute_compaction(
417
445
  deltacat_storage_kwargs=params.deltacat_storage_kwargs,
418
446
  delete_strategy=delete_strategy,
419
447
  delete_file_envelopes=delete_file_envelopes,
448
+ memory_logs_enabled=params.memory_logs_enabled,
420
449
  )
421
450
  }
422
451
 
@@ -438,11 +467,11 @@ def _execute_compaction(
438
467
  merge_end = time.monotonic()
439
468
 
440
469
  total_dd_record_count = sum([ddr.deduped_record_count for ddr in merge_results])
441
- total_dropped_record_count = sum(
470
+ total_deleted_record_count = sum(
442
471
  [ddr.deleted_record_count for ddr in merge_results]
443
472
  )
444
473
  logger.info(
445
- f"Deduped {total_dd_record_count} records and dropped {total_dropped_record_count} records..."
474
+ f"Deduped {total_dd_record_count} records and deleted {total_deleted_record_count} records..."
446
475
  )
447
476
 
448
477
  compaction_audit.set_input_records(total_input_records_count.item())
@@ -456,7 +485,7 @@ def _execute_compaction(
456
485
  )
457
486
 
458
487
  compaction_audit.set_records_deduped(total_dd_record_count.item())
459
-
488
+ compaction_audit.set_records_deleted(total_deleted_record_count.item())
460
489
  mat_results = []
461
490
  for merge_result in merge_results:
462
491
  mat_results.extend(merge_result.materialize_results)
@@ -503,7 +532,7 @@ def _execute_compaction(
503
532
  record_info_msg = (
504
533
  f"Hash bucket records: {total_hb_record_count},"
505
534
  f" Deduped records: {total_dd_record_count}, "
506
- f" Dropped records: {total_dropped_record_count}, "
535
+ f" Deleted records: {total_deleted_record_count}, "
507
536
  f" Materialized records: {merged_delta.meta.record_count}"
508
537
  )
509
538
  logger.info(record_info_msg)
@@ -603,7 +632,6 @@ def _execute_compaction(
603
632
  f"partition-{params.source_partition_locator.partition_values},"
604
633
  f"compacted at: {params.last_stream_position_to_compact},"
605
634
  )
606
-
607
635
  return (
608
636
  compacted_partition,
609
637
  new_round_completion_info,
@@ -22,6 +22,7 @@ class HashBucketInput(Dict):
22
22
  object_store: Optional[IObjectStore] = None,
23
23
  deltacat_storage=unimplemented_deltacat_storage,
24
24
  deltacat_storage_kwargs: Optional[Dict[str, Any]] = None,
25
+ memory_logs_enabled: Optional[bool] = None,
25
26
  ) -> HashBucketInput:
26
27
 
27
28
  result = HashBucketInput()
@@ -36,6 +37,7 @@ class HashBucketInput(Dict):
36
37
  result["object_store"] = object_store
37
38
  result["deltacat_storage"] = deltacat_storage
38
39
  result["deltacat_storage_kwargs"] = deltacat_storage_kwargs or {}
40
+ result["memory_logs_enabled"] = memory_logs_enabled
39
41
 
40
42
  return result
41
43
 
@@ -82,3 +84,7 @@ class HashBucketInput(Dict):
82
84
  @property
83
85
  def deltacat_storage_kwargs(self) -> Optional[Dict[str, Any]]:
84
86
  return self.get("deltacat_storage_kwargs")
87
+
88
+ @property
89
+ def memory_logs_enabled(self) -> Optional[bool]:
90
+ return self.get("memory_logs_enabled")
@@ -46,6 +46,7 @@ class MergeInput(Dict):
46
46
  delete_file_envelopes: Optional[List] = None,
47
47
  deltacat_storage=unimplemented_deltacat_storage,
48
48
  deltacat_storage_kwargs: Optional[Dict[str, Any]] = None,
49
+ memory_logs_enabled: Optional[bool] = None,
49
50
  ) -> MergeInput:
50
51
 
51
52
  result = MergeInput()
@@ -67,6 +68,7 @@ class MergeInput(Dict):
67
68
  result["delete_strategy"] = delete_strategy
68
69
  result["deltacat_storage"] = deltacat_storage
69
70
  result["deltacat_storage_kwargs"] = deltacat_storage_kwargs or {}
71
+ result["memory_logs_enabled"] = memory_logs_enabled
70
72
  return result
71
73
 
72
74
  @property
@@ -133,6 +135,10 @@ class MergeInput(Dict):
133
135
  def deltacat_storage_kwargs(self) -> Optional[Dict[str, Any]]:
134
136
  return self.get("deltacat_storage_kwargs")
135
137
 
138
+ @property
139
+ def memory_logs_enabled(self) -> Optional[bool]:
140
+ return self.get("memory_logs_enabled")
141
+
136
142
  @property
137
143
  def delete_file_envelopes(
138
144
  self,
@@ -142,7 +142,8 @@ def hash_bucket(input: HashBucketInput) -> HashBucketResult:
142
142
  f"({process_util.max_memory/BYTES_PER_GIBIBYTE} GB)"
143
143
  )
144
144
 
145
- process_util.schedule_callback(log_peak_memory, 10)
145
+ if input.memory_logs_enabled:
146
+ process_util.schedule_callback(log_peak_memory, 10)
146
147
 
147
148
  hash_bucket_result, duration = timed_invocation(
148
149
  func=_timed_hash_bucket, input=input
@@ -12,6 +12,7 @@ from uuid import uuid4
12
12
  from deltacat import logs
13
13
  from typing import Callable, Iterator, List, Optional, Tuple
14
14
  from deltacat.compute.compactor_v2.model.merge_result import MergeResult
15
+ from deltacat.compute.compactor_v2.model.merge_file_group import MergeFileGroup
15
16
  from deltacat.compute.compactor.model.materialize_result import MaterializeResult
16
17
  from deltacat.compute.compactor.model.pyarrow_write_result import PyArrowWriteResult
17
18
  from deltacat.compute.compactor import RoundCompletionInfo, DeltaFileEnvelope
@@ -269,6 +270,24 @@ def _has_previous_compacted_table(input: MergeInput, hb_idx: int) -> bool:
269
270
  )
270
271
 
271
272
 
273
+ def _can_copy_by_reference(
274
+ has_delete: bool, merge_file_group: MergeFileGroup, input: MergeInput
275
+ ) -> bool:
276
+ """
277
+ Can copy by reference only if there are no deletes to merge in
278
+ and previous compacted stream id matches that of new stream
279
+ """
280
+ return (
281
+ not has_delete
282
+ and not merge_file_group.dfe_groups
283
+ and input.round_completion_info is not None
284
+ and (
285
+ input.write_to_partition.stream_id
286
+ == input.round_completion_info.compacted_delta_locator.stream_id
287
+ )
288
+ )
289
+
290
+
272
291
  def _flatten_dfe_list(
273
292
  df_envelopes_list: List[List[DeltaFileEnvelope]],
274
293
  ) -> List[DeltaFileEnvelope]:
@@ -349,7 +368,7 @@ def _compact_tables(
349
368
  1. The compacted PyArrow table.
350
369
  2. The total number of records in the incremental data.
351
370
  3. The total number of deduplicated records.
352
- 4. The total number of dropped records due to DELETE operations.
371
+ 4. The total number of deleted records due to DELETE operations.
353
372
  """
354
373
  df_envelopes: List[DeltaFileEnvelope] = _flatten_dfe_list(dfe_list)
355
374
  delete_file_envelopes = input.delete_file_envelopes or []
@@ -479,10 +498,12 @@ def _timed_merge(input: MergeInput) -> MergeResult:
479
498
  assert (
480
499
  input.delete_strategy is not None
481
500
  ), "Merge input missing delete_strategy"
482
- if not has_delete and not merge_file_group.dfe_groups:
483
- # Can copy by reference only if there are no deletes to merge in
501
+ if _can_copy_by_reference(
502
+ has_delete=has_delete, merge_file_group=merge_file_group, input=input
503
+ ):
484
504
  hb_index_copy_by_ref_ids.append(merge_file_group.hb_index)
485
505
  continue
506
+
486
507
  if _has_previous_compacted_table(input, merge_file_group.hb_index):
487
508
  compacted_table = _download_compacted_table(
488
509
  hb_index=merge_file_group.hb_index,
@@ -548,7 +569,8 @@ def merge(input: MergeInput) -> MergeResult:
548
569
  f"({process_util.max_memory/BYTES_PER_GIBIBYTE} GB)"
549
570
  )
550
571
 
551
- process_util.schedule_callback(log_peak_memory, 10)
572
+ if input.memory_logs_enabled:
573
+ process_util.schedule_callback(log_peak_memory, 10)
552
574
 
553
575
  merge_result, duration = timed_invocation(func=_timed_merge, input=input)
554
576
 
@@ -1,7 +1,10 @@
1
1
  import botocore
2
2
  import logging
3
- from typing import Dict, Optional, List, Tuple
3
+ from typing import Dict, Optional, List, Tuple, Any
4
4
  from deltacat import logs
5
+ from deltacat.compute.compactor_v2.model.merge_file_group import (
6
+ LocalMergeFileGroupsProvider,
7
+ )
5
8
  from deltacat.types.media import ContentEncoding, ContentType
6
9
  from deltacat.types.partial_download import PartialParquetParameters
7
10
  from deltacat.storage import (
@@ -15,7 +18,6 @@ from deltacat.compute.compactor_v2.utils.primary_key_index import (
15
18
  hash_group_index_to_hash_bucket_indices,
16
19
  )
17
20
  from deltacat.compute.compactor_v2.constants import (
18
- TOTAL_MEMORY_BUFFER_PERCENTAGE,
19
21
  PARQUET_TO_PYARROW_INFLATION,
20
22
  )
21
23
 
@@ -133,8 +135,10 @@ def hash_bucket_resource_options_provider(
133
135
  item: DeltaAnnotated,
134
136
  previous_inflation: float,
135
137
  average_record_size_bytes: float,
138
+ total_memory_buffer_percentage: int,
136
139
  primary_keys: List[str] = None,
137
140
  ray_custom_resources: Optional[Dict] = None,
141
+ memory_logs_enabled: Optional[bool] = None,
138
142
  **kwargs,
139
143
  ) -> Dict:
140
144
  debug_memory_params = {"hash_bucket_task_index": index}
@@ -189,10 +193,11 @@ def hash_bucket_resource_options_provider(
189
193
  debug_memory_params["average_record_size_bytes"] = average_record_size_bytes
190
194
 
191
195
  # Consider buffer
192
- total_memory = total_memory * (1 + TOTAL_MEMORY_BUFFER_PERCENTAGE / 100.0)
196
+ total_memory = total_memory * (1 + total_memory_buffer_percentage / 100.0)
193
197
  debug_memory_params["total_memory_with_buffer"] = total_memory
194
- logger.debug(
195
- f"[Hash bucket task {index}]: Params used for calculating hash bucketing memory: {debug_memory_params}"
198
+ logger.debug_conditional(
199
+ f"[Hash bucket task {index}]: Params used for calculating hash bucketing memory: {debug_memory_params}",
200
+ memory_logs_enabled,
196
201
  )
197
202
 
198
203
  return get_task_options(0.01, total_memory, ray_custom_resources)
@@ -204,12 +209,14 @@ def merge_resource_options_provider(
204
209
  num_hash_groups: int,
205
210
  hash_group_size_bytes: Dict[int, int],
206
211
  hash_group_num_rows: Dict[int, int],
212
+ total_memory_buffer_percentage: int,
207
213
  round_completion_info: Optional[RoundCompletionInfo] = None,
208
214
  compacted_delta_manifest: Optional[Manifest] = None,
209
215
  ray_custom_resources: Optional[Dict] = None,
210
216
  primary_keys: Optional[List[str]] = None,
211
217
  deltacat_storage=unimplemented_deltacat_storage,
212
218
  deltacat_storage_kwargs: Optional[Dict] = {},
219
+ memory_logs_enabled: Optional[bool] = None,
213
220
  **kwargs,
214
221
  ) -> Dict:
215
222
  debug_memory_params = {"merge_task_index": index}
@@ -224,6 +231,84 @@ def merge_resource_options_provider(
224
231
  pk_size_bytes = data_size
225
232
  incremental_index_array_size = num_rows * 4
226
233
 
234
+ return get_merge_task_options(
235
+ index,
236
+ hb_group_idx,
237
+ data_size,
238
+ pk_size_bytes,
239
+ num_rows,
240
+ num_hash_groups,
241
+ total_memory_buffer_percentage,
242
+ incremental_index_array_size,
243
+ debug_memory_params,
244
+ ray_custom_resources,
245
+ round_completion_info=round_completion_info,
246
+ compacted_delta_manifest=compacted_delta_manifest,
247
+ primary_keys=primary_keys,
248
+ deltacat_storage=deltacat_storage,
249
+ deltacat_storage_kwargs=deltacat_storage_kwargs,
250
+ memory_logs_enabled=memory_logs_enabled,
251
+ )
252
+
253
+
254
+ def local_merge_resource_options_provider(
255
+ estimated_da_size: float,
256
+ estimated_num_rows: int,
257
+ total_memory_buffer_percentage: int,
258
+ round_completion_info: Optional[RoundCompletionInfo] = None,
259
+ compacted_delta_manifest: Optional[Manifest] = None,
260
+ ray_custom_resources: Optional[Dict] = None,
261
+ primary_keys: Optional[List[str]] = None,
262
+ deltacat_storage=unimplemented_deltacat_storage,
263
+ deltacat_storage_kwargs: Optional[Dict] = {},
264
+ memory_logs_enabled: Optional[bool] = None,
265
+ **kwargs,
266
+ ) -> Dict:
267
+ index = hb_group_idx = LocalMergeFileGroupsProvider.LOCAL_HASH_BUCKET_INDEX
268
+ debug_memory_params = {"merge_task_index": index}
269
+
270
+ # upper bound for pk size of incremental
271
+ pk_size_bytes = estimated_da_size
272
+ incremental_index_array_size = estimated_num_rows * 4
273
+
274
+ return get_merge_task_options(
275
+ index=index,
276
+ hb_group_idx=hb_group_idx,
277
+ data_size=estimated_da_size,
278
+ pk_size_bytes=pk_size_bytes,
279
+ num_rows=estimated_num_rows,
280
+ num_hash_groups=1,
281
+ incremental_index_array_size=incremental_index_array_size,
282
+ total_memory_buffer_percentage=total_memory_buffer_percentage,
283
+ debug_memory_params=debug_memory_params,
284
+ ray_custom_resources=ray_custom_resources,
285
+ round_completion_info=round_completion_info,
286
+ compacted_delta_manifest=compacted_delta_manifest,
287
+ primary_keys=primary_keys,
288
+ deltacat_storage=deltacat_storage,
289
+ deltacat_storage_kwargs=deltacat_storage_kwargs,
290
+ memory_logs_enabled=memory_logs_enabled,
291
+ )
292
+
293
+
294
+ def get_merge_task_options(
295
+ index: int,
296
+ hb_group_idx: int,
297
+ data_size: float,
298
+ pk_size_bytes: float,
299
+ num_rows: int,
300
+ num_hash_groups: int,
301
+ total_memory_buffer_percentage: int,
302
+ incremental_index_array_size: int,
303
+ debug_memory_params: Dict[str, Any],
304
+ ray_custom_resources: Optional[Dict],
305
+ round_completion_info: Optional[RoundCompletionInfo] = None,
306
+ compacted_delta_manifest: Optional[Manifest] = None,
307
+ primary_keys: Optional[List[str]] = None,
308
+ deltacat_storage=unimplemented_deltacat_storage,
309
+ deltacat_storage_kwargs: Optional[Dict] = {},
310
+ memory_logs_enabled: Optional[bool] = None,
311
+ ) -> Dict[str, Any]:
227
312
  if (
228
313
  round_completion_info
229
314
  and compacted_delta_manifest
@@ -296,10 +381,11 @@ def merge_resource_options_provider(
296
381
  debug_memory_params["incremental_index_array_size"] = incremental_index_array_size
297
382
  debug_memory_params["total_memory"] = total_memory
298
383
 
299
- total_memory = total_memory * (1 + TOTAL_MEMORY_BUFFER_PERCENTAGE / 100.0)
384
+ total_memory = total_memory * (1 + total_memory_buffer_percentage / 100.0)
300
385
  debug_memory_params["total_memory_with_buffer"] = total_memory
301
- logger.debug(
302
- f"[Merge task {index}]: Params used for calculating merge memory: {debug_memory_params}"
386
+ logger.debug_conditional(
387
+ f"[Merge task {index}]: Params used for calculating merge memory: {debug_memory_params}",
388
+ memory_logs_enabled,
303
389
  )
304
390
 
305
391
  return get_task_options(0.01, total_memory, ray_custom_resources)
@@ -181,15 +181,35 @@ class MemcachedObjectStore(IObjectStore):
181
181
  for chunk_index in range(chunk_count):
182
182
  ref = self._create_ref(uid, ip, chunk_index)
183
183
  chunk = client.get(ref)
184
+ if chunk is None:
185
+ raise ValueError(
186
+ f"Expected uid: {uid}, chunk index: {chunk_index} from client ip: {ip}"
187
+ f" to be non-empty."
188
+ )
184
189
  serialized.extend(chunk)
185
190
 
186
191
  return cloudpickle.loads(serialized)
187
192
 
193
+ def clear(self) -> bool:
194
+ flushed = all(
195
+ [
196
+ self._get_client_by_ip(ip).flush_all(noreply=False)
197
+ for ip in self.storage_node_ips
198
+ ]
199
+ )
200
+ self.client_cache.clear()
201
+
202
+ if flushed:
203
+ logger.info("Successfully cleared cache contents.")
204
+
205
+ return flushed
206
+
188
207
  def close(self) -> None:
189
208
  for client in self.client_cache.values():
190
209
  client.close()
191
210
 
192
211
  self.client_cache.clear()
212
+ logger.info("Successfully closed object store clients.")
193
213
 
194
214
  def _create_ref(self, uid, ip, chunk_index) -> str:
195
215
  return f"{uid}{self.SEPARATOR}{ip}{self.SEPARATOR}{chunk_index}"
deltacat/logs.py CHANGED
@@ -2,7 +2,7 @@ import logging
2
2
  import os
3
3
  import pathlib
4
4
  from logging import FileHandler, Handler, Logger, LoggerAdapter, handlers
5
- from typing import Union
5
+ from typing import Any, Dict, Optional, Union
6
6
 
7
7
  import ray
8
8
  from ray.runtime_context import RuntimeContext
@@ -26,7 +26,32 @@ DEFAULT_MAX_BYTES_PER_LOG = 2 ^ 20 * 256 # 256 MiB
26
26
  DEFAULT_BACKUP_COUNT = 0
27
27
 
28
28
 
29
- class RayRuntimeContextLoggerAdapter(logging.LoggerAdapter):
29
+ class DeltaCATLoggerAdapter(logging.LoggerAdapter):
30
+ """
31
+ Logger Adapter class with additional functionality
32
+ """
33
+
34
+ def __init__(self, logger: Logger, extra: Optional[Dict[str, Any]] = {}):
35
+ super().__init__(logger, extra)
36
+
37
+ def debug_conditional(self, msg, do_print: bool, *args, **kwargs):
38
+ if do_print:
39
+ self.debug(msg, *args, **kwargs)
40
+
41
+ def info_conditional(self, msg, do_print: bool, *args, **kwargs):
42
+ if do_print:
43
+ self.info(msg, *args, **kwargs)
44
+
45
+ def warning_conditional(self, msg, do_print: bool, *args, **kwargs):
46
+ if do_print:
47
+ self.warning(msg, *args, **kwargs)
48
+
49
+ def error_conditional(self, msg, do_print: bool, *args, **kwargs):
50
+ if do_print:
51
+ self.error(msg, *args, **kwargs)
52
+
53
+
54
+ class RayRuntimeContextLoggerAdapter(DeltaCATLoggerAdapter):
30
55
  """
31
56
  Logger Adapter for injecting Ray Runtime Context into logging messages.
32
57
  """
@@ -147,6 +172,8 @@ def _configure_logger(
147
172
  ray_runtime_ctx = ray.get_runtime_context()
148
173
  if ray_runtime_ctx.worker.connected:
149
174
  logger = RayRuntimeContextLoggerAdapter(logger, ray_runtime_ctx)
175
+ else:
176
+ logger = DeltaCATLoggerAdapter(logger)
150
177
 
151
178
  return logger
152
179
 
@@ -72,6 +72,7 @@ class TestCompactPartitionParams(unittest.TestCase):
72
72
  "partitionValues": [],
73
73
  "partitionId": "79612ea39ac5493eae925abe60767d42",
74
74
  },
75
+ "memory_logs_enabled": True,
75
76
  "metrics_config": MetricsConfig("us-east-1", MetricsTarget.CLOUDWATCH_EMF),
76
77
  }
77
78
 
@@ -135,6 +136,10 @@ class TestCompactPartitionParams(unittest.TestCase):
135
136
  json.loads(serialized_params)["destination_partition_locator"]
136
137
  == params.destination_partition_locator
137
138
  )
139
+ assert (
140
+ json.loads(serialized_params)["memory_logs_enabled"]
141
+ == params.memory_logs_enabled
142
+ )
138
143
  assert (
139
144
  json.loads(serialized_params)["metrics_config"]["metrics_target"]
140
145
  == params.metrics_config.metrics_target
@@ -25,6 +25,10 @@ class MockPyMemcacheClient:
25
25
  def get(self, key, *args, **kwargs):
26
26
  return self.store.get(key)
27
27
 
28
+ def flush_all(self, *args, **kwargs):
29
+ for key, value in self.store.items():
30
+ self.store[key] = None
31
+
28
32
 
29
33
  class TestMemcachedObjectStore(unittest.TestCase):
30
34
 
@@ -192,3 +196,18 @@ class TestMemcachedObjectStore(unittest.TestCase):
192
196
  # assert
193
197
  result = self.object_store.get(ref)
194
198
  self.assertEqual(result, self.TEST_VALUE_LARGE)
199
+
200
+ @mock.patch("deltacat.io.memcached_object_store.Client")
201
+ @mock.patch("deltacat.io.memcached_object_store.RetryingClient")
202
+ def test_clear_sanity(self, mock_retrying_client, mock_client):
203
+ # setup
204
+ mock_client.return_value = MockPyMemcacheClient()
205
+ mock_retrying_client.return_value = mock_client.return_value
206
+
207
+ # action
208
+ ref = self.object_store.put(self.TEST_VALUE_LARGE)
209
+ self.object_store.clear()
210
+
211
+ # assert
212
+ with self.assertRaises(ValueError):
213
+ self.object_store.get(ref)
@@ -36,13 +36,15 @@ class ClusterUtilization:
36
36
  used_resources[key] = cluster_resources[key] - available_resources[key]
37
37
 
38
38
  self.total_memory_bytes = cluster_resources.get("memory")
39
- self.used_memory_bytes = used_resources.get("memory")
39
+ self.used_memory_bytes = used_resources.get("memory", 0.0)
40
40
  self.total_cpu = cluster_resources.get("CPU")
41
- self.used_cpu = used_resources.get("CPU")
41
+ self.used_cpu = used_resources.get("CPU", 0)
42
42
  self.total_object_store_memory_bytes = cluster_resources.get(
43
43
  "object_store_memory"
44
44
  )
45
- self.used_object_store_memory_bytes = used_resources.get("object_store_memory")
45
+ self.used_object_store_memory_bytes = used_resources.get(
46
+ "object_store_memory", 0.0
47
+ )
46
48
  self.used_memory_percent = (
47
49
  self.used_memory_bytes / self.total_memory_bytes
48
50
  ) * 100
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: deltacat
3
- Version: 1.1.0
3
+ Version: 1.1.1
4
4
  Summary: A scalable, fast, ACID-compliant Data Catalog powered by Ray.
5
5
  Home-page: https://github.com/ray-project/deltacat
6
6
  Author: Ray Team
@@ -1,7 +1,7 @@
1
- deltacat/__init__.py,sha256=jgsxhhooY-sexT3kAhQirASpDPtehwb4RDqDt_3rcaQ,1777
1
+ deltacat/__init__.py,sha256=PeDnE7G_w2Gwkfg1VVp1mGIZm0_-WoyYbu7SlmoCFHs,1777
2
2
  deltacat/constants.py,sha256=_6oRI-3yp5c8J1qKGQZrt89I9-ttT_gSSvVsJ0h8Duc,1939
3
3
  deltacat/exceptions.py,sha256=xqZf8CwysNYP2d39pf27OnXGStPREgBgIM-e2Tts-TI,199
4
- deltacat/logs.py,sha256=9XWuTBoWhhAF9rAL6t9veXmnAlJHsaqk0lTxteVPqyQ,5674
4
+ deltacat/logs.py,sha256=YT26oj-oKZReyBEhiBQU5jc246aSu_d4B2bZcUVBHmE,6550
5
5
  deltacat/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  deltacat/aws/clients.py,sha256=WKgbgaq8CacH81nvvcqrjdshGtYvQicvBeOLg1m7wCA,6501
7
7
  deltacat/aws/constants.py,sha256=luXWMO_8eatq8f9NlFjNM7q362j77JwzTM2BEVS_8-8,353
@@ -24,8 +24,8 @@ deltacat/compute/compactor/__init__.py,sha256=ivpOPve1yKi3Vz3tVgp-eeFMNEeUSf-dlR
24
24
  deltacat/compute/compactor/compaction_session.py,sha256=bJpNBSTW7Raoa1gpojDpmVVqQGpvX0AwrusHQhUANcI,27612
25
25
  deltacat/compute/compactor/repartition_session.py,sha256=f5BTTGNv365qSuTioL7QUuVm-px_l8-zz-OC_p7gXt4,7240
26
26
  deltacat/compute/compactor/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- deltacat/compute/compactor/model/compact_partition_params.py,sha256=DdM6YsA5CSAMAwqQ5yscxR-NWadnItpgX18JikdJoQ4,14344
28
- deltacat/compute/compactor/model/compaction_session_audit_info.py,sha256=o8O0v3nOc7m1ZR4W0wQkTdsMyFL24LoMc9kzUo8i5uc,30174
27
+ deltacat/compute/compactor/model/compact_partition_params.py,sha256=I5DHVv4a_Pb3hlfWf5pyUeKcxEtvMu8LLEWFRH9qdfE,15195
28
+ deltacat/compute/compactor/model/compaction_session_audit_info.py,sha256=Aoae5KNmbdYt48utFQR_zrjHTkC9JNd4jPhQmyJji-A,30547
29
29
  deltacat/compute/compactor/model/compactor_version.py,sha256=RwRvManiCxZmzjAWzm1OPDxjB1BEHu1d0fBJyGhXKxA,87
30
30
  deltacat/compute/compactor/model/dedupe_result.py,sha256=1OCV944qJdLQ_-8scisVKl45ej1eRv9OV539QYZtQ-U,292
31
31
  deltacat/compute/compactor/model/delta_annotated.py,sha256=NERB9rOtYg-xzBwvqGJ7_hBOzBC7g6X5M9-Cq5pbdH8,12258
@@ -50,7 +50,7 @@ deltacat/compute/compactor/utils/round_completion_file.py,sha256=DmZfHeAXlQn0DDd
50
50
  deltacat/compute/compactor/utils/sort_key.py,sha256=oK6otg-CSsma6zlGPaKg-KNEvcZRG2NqBlCw1X3_FBc,2397
51
51
  deltacat/compute/compactor/utils/system_columns.py,sha256=CNIgAGos0xAGEpdaQIH7KfbSRrGZgjRbItXMararqXQ,9399
52
52
  deltacat/compute/compactor_v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
- deltacat/compute/compactor_v2/compaction_session.py,sha256=8z7fQCHkL1Ei70_HdBh_Ckkstb7B_FiG_rfglJRouLQ,23668
53
+ deltacat/compute/compactor_v2/compaction_session.py,sha256=xAxiTOxHffRvPqkv4ObGM-NWdpxRRMyrS8WWZWrgTFQ,25141
54
54
  deltacat/compute/compactor_v2/constants.py,sha256=yZgzFD59wiXbXiTVgYPWRodZGpngiSBNFB2jmoZ4fps,1471
55
55
  deltacat/compute/compactor_v2/deletes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
56
  deltacat/compute/compactor_v2/deletes/delete_file_envelope.py,sha256=AeuH9JRMwp6mvQf6P2cqL92hUEtResQq6qUTS0kIKac,3111
@@ -59,14 +59,14 @@ deltacat/compute/compactor_v2/deletes/delete_strategy_equality_delete.py,sha256=
59
59
  deltacat/compute/compactor_v2/deletes/model.py,sha256=kW7kfRe4jVNMnsWQrl0nyKdDpvB9mbJND-MVzAajbAI,558
60
60
  deltacat/compute/compactor_v2/deletes/utils.py,sha256=g63imGECPpPK9eHdde-6qyCg8_RjXCLF2UdfckPk0h4,6468
61
61
  deltacat/compute/compactor_v2/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
- deltacat/compute/compactor_v2/model/hash_bucket_input.py,sha256=HS1BLgNCjQoqe7EuM9baQWE6U4BFqU2PVEWFEF725VE,2815
62
+ deltacat/compute/compactor_v2/model/hash_bucket_input.py,sha256=iJy8kLi1dIpFIyfoAjkaAtZvg8Np1z7BsUNGAcWfFm4,3042
63
63
  deltacat/compute/compactor_v2/model/hash_bucket_result.py,sha256=EsY9BPPywhmxlcLKn3kGWzAX4s4BTR2vYyPUB-wAEOc,309
64
64
  deltacat/compute/compactor_v2/model/merge_file_group.py,sha256=1o86t9lc3K6ZvtViVO1SVljCj6f0B3MfB3hqtGm2S0s,7410
65
- deltacat/compute/compactor_v2/model/merge_input.py,sha256=EBfV2SNQjsEnbwKHFnumqGSfALzmz8vdMf41RxZNhZ0,5189
65
+ deltacat/compute/compactor_v2/model/merge_input.py,sha256=ITRBR8gMbJpeRkZhRaVzGEEk3F2WqS2LwEkjd5zcaMQ,5416
66
66
  deltacat/compute/compactor_v2/model/merge_result.py,sha256=_IZTCStpb4UKiRCJYA3g6EhAqjrw0t9vmoDAN8kIK-Y,436
67
67
  deltacat/compute/compactor_v2/steps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
- deltacat/compute/compactor_v2/steps/hash_bucket.py,sha256=QUNgYrxEp3ODr8YjCpIvXNKDQAxMaGhINgB9_jG1jNs,6282
69
- deltacat/compute/compactor_v2/steps/merge.py,sha256=kYeLofIpYXF1FgNyXPIcRRr7SQYYK_DbkT8LPJJZrsw,20731
68
+ deltacat/compute/compactor_v2/steps/hash_bucket.py,sha256=Kuhgh1y12t4V9rP67bdalQF6_sZiobfAK3tvOka8IWA,6324
69
+ deltacat/compute/compactor_v2/steps/merge.py,sha256=dNGE_UtQmptYWj59_XQBoFrB6iNWYE37iup81HqWcAU,21394
70
70
  deltacat/compute/compactor_v2/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
71
  deltacat/compute/compactor_v2/utils/content_type_params.py,sha256=rNKZisxGrLQOkwX8eHUQiFoTR1V-E66pMqWigtrs618,2156
72
72
  deltacat/compute/compactor_v2/utils/dedupe.py,sha256=62tFCY2iRP7I3-45GCIYs6_SJsQl8C5lBEr8gbNfbsw,1932
@@ -74,7 +74,7 @@ deltacat/compute/compactor_v2/utils/delta.py,sha256=8hjkDeIIkSX-gAQ2utQSp2sZcO2t
74
74
  deltacat/compute/compactor_v2/utils/io.py,sha256=jgIfwrfH2mTFUx1M0TgwZGGfrS4IXjP1PmqwaQmNAJM,5092
75
75
  deltacat/compute/compactor_v2/utils/merge.py,sha256=hK4Y7acrtgfvWWTz-fAGznEg6qn6dBYu8blQUQVHhs0,5244
76
76
  deltacat/compute/compactor_v2/utils/primary_key_index.py,sha256=MAscmL35WfwN7Is72aFlD_cGhxtZgjRwwR5kS9Yn2uU,11393
77
- deltacat/compute/compactor_v2/utils/task_options.py,sha256=Ndhff9F_zff6zX3mw4AztHkvSBgR4O8SgMUgwq3rvyM,10601
77
+ deltacat/compute/compactor_v2/utils/task_options.py,sha256=MCY0Sz5NCgNMaY92W8p87FvvDB91mnPQ4AhL8ix3BiA,13780
78
78
  deltacat/compute/merge_on_read/__init__.py,sha256=ckbgngmqPjYBYz_NySsR1vNTOb_hNpeL1sYkZKvBI9M,214
79
79
  deltacat/compute/merge_on_read/daft.py,sha256=1oC38u5ig_aTrq7EzyWBo8Ui54rb6yERYMk-vEFbpxM,1400
80
80
  deltacat/compute/merge_on_read/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -109,7 +109,7 @@ deltacat/compute/stats/utils/manifest_stats_file.py,sha256=PtqW5Zc5e09HcfiAgvoZH
109
109
  deltacat/io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
110
  deltacat/io/dataset.py,sha256=8w9sPVDpGnjjGVDWB39YSKWxq4zRv9VEfDtj7PYwjqM,3755
111
111
  deltacat/io/file_object_store.py,sha256=HCFeXu9cWXPXVk54MHel_nw3-wIuzhMt2RI6jKzjRYM,1346
112
- deltacat/io/memcached_object_store.py,sha256=dqAIh2hQrEHDv-UOO4n4nRpb9KapVWiev09ewSS2O90,8555
112
+ deltacat/io/memcached_object_store.py,sha256=4Sc7Tue3giKBrRm6zM2G0ZrvDCtubnIp1UvsqA2i9M0,9185
113
113
  deltacat/io/object_store.py,sha256=X6221ZuVx8NOyKUesz8LvjvQ_4vZ6p2RWV6VISL17AY,1576
114
114
  deltacat/io/ray_plasma_object_store.py,sha256=TyoUPWybE_cSISZ2SQa3YfD93QWMp0r82-6WnoVSmzk,905
115
115
  deltacat/io/read_api.py,sha256=BhkjL3xjY-fsa62AA9Yv20_88uTskn4_Bv2W6VmMXVA,7023
@@ -141,7 +141,7 @@ deltacat/tests/compute/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
141
141
  deltacat/tests/compute/compact_partition_rebase_then_incremental_test_cases.py,sha256=SaYQI30d1sxOBVs-Qj9VsMtigp4tWaRFFPmsPdahILc,72082
142
142
  deltacat/tests/compute/compact_partition_test_cases.py,sha256=b6wVg1UP0pahtrS3dojk-_1tSXHjCWd95XBo4J6KEAU,20092
143
143
  deltacat/tests/compute/test_compact_partition_incremental.py,sha256=G_xUERQjtBzAVfipzucdR8ATJviaVwTsj-5rRWVgYJY,10271
144
- deltacat/tests/compute/test_compact_partition_params.py,sha256=MIzIcBscwFA1W-cfTTxVx0zcgbrs8D4bI9Hy4TF5eRo,8322
144
+ deltacat/tests/compute/test_compact_partition_params.py,sha256=Dm5eLyHo8oGMeO3XBbpj1rZqHtPZ1hAB7z2qvzc4Lxk,8497
145
145
  deltacat/tests/compute/test_compact_partition_rebase_then_incremental.py,sha256=n6Qy-_STWgy3j02QyfZMUChIlHqlTfZjQ-G8yDppvyM,14077
146
146
  deltacat/tests/compute/test_util_common.py,sha256=Skz0ZfHzidArZhIzRDHOYt-5uGBwx6MRfKZpeBnzh9w,6055
147
147
  deltacat/tests/compute/test_util_constant.py,sha256=4o-W3E7r7jhFl1A3OFLLrdKnwcF46zx4lEIDY8ONJ3c,929
@@ -159,7 +159,7 @@ deltacat/tests/compute/compactor_v2/utils/test_task_options.py,sha256=4fc5MJTLm3
159
159
  deltacat/tests/io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
160
160
  deltacat/tests/io/test_cloudpickle_bug_fix.py,sha256=qnYJg_S-nsLai77a4_I3Qs2Jtr_KWQJOxyl96f9PgHA,1376
161
161
  deltacat/tests/io/test_file_object_store.py,sha256=bHEJRleVHwvk-bbvAlNOFnOA_tbR8i0SxtsllMTb8w0,2559
162
- deltacat/tests/io/test_memcached_object_store.py,sha256=gUVYycPkNpq9XxotdJwFZ2HOmNZqwoa1nAC57ZL3TBo,7392
162
+ deltacat/tests/io/test_memcached_object_store.py,sha256=25SB5xTMAG0HKwZwsDLhMreJ0dA6zrCDmHuY955YeLA,8070
163
163
  deltacat/tests/io/test_ray_plasma_object_store.py,sha256=-wJZP6lRtEOogR25wjEiIBGz_lpvWVihwlZ5GqandZU,1911
164
164
  deltacat/tests/io/test_redis_object_store.py,sha256=sZrXrYjkw8u_XrvFilhBbLc8PPnZiuMKa1_Bt9ka5qs,3838
165
165
  deltacat/tests/io/test_s3_object_store.py,sha256=4b7PYEfQJnYGUz6fcLFWVVyRHTlH_yd8CIaCv9l33Gg,1900
@@ -193,7 +193,7 @@ deltacat/utils/pandas.py,sha256=GfwjYb8FUSEeoBdXZI1_NJkdjxPMbCCUhlyRfGbDkn8,9562
193
193
  deltacat/utils/performance.py,sha256=7ZLaMkS1ehPSIhT5uOQVBHvjC70iKHzoFquFo-KL0PI,645
194
194
  deltacat/utils/placement.py,sha256=S80CwD1eEK47lQNr0xTmF9kq092-z6lTTmOOBv8cW_o,11723
195
195
  deltacat/utils/pyarrow.py,sha256=gYcoRhQoBoAFo69WNijMobrLGta4VASg8VarWPiB34Y,28979
196
- deltacat/utils/resources.py,sha256=UhxEnRMP2ts5iFR-h9ORmHe4pmJlLbMWZT80GsLVPEk,8218
196
+ deltacat/utils/resources.py,sha256=Ax1OgLLbZI4oYpp4Ki27OLaST-7I-AJgZwU87FVfY8g,8253
197
197
  deltacat/utils/s3fs.py,sha256=PmUJ5Fm1WmD-_zp_M6yd9VbXvIoJuBeK6ApOdJJApLE,662
198
198
  deltacat/utils/schema.py,sha256=m4Wm4ZQcpttzOUxex4dVneGlHy1_E36HspTcjNYzvVM,1564
199
199
  deltacat/utils/ray_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -202,8 +202,8 @@ deltacat/utils/ray_utils/concurrency.py,sha256=JDVwMiQWrmuSlyCWAoiq9ctoJ0XADEfDD
202
202
  deltacat/utils/ray_utils/dataset.py,sha256=SIljK3UkSqQ6Ntit_iSiYt9yYjN_gGrCTX6_72XdQ3w,3244
203
203
  deltacat/utils/ray_utils/performance.py,sha256=d7JFM7vTXHzkGx9qNQcZzUWajnqINvYRwaM088_FpsE,464
204
204
  deltacat/utils/ray_utils/runtime.py,sha256=5eaBWTDm0IXVoc5Y6aacoVB-f0Mnv-K2ewyTSjHKHwM,5009
205
- deltacat-1.1.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
206
- deltacat-1.1.0.dist-info/METADATA,sha256=rRb66_RxRcgvMfnTnwLGsvubmhW83uhLLIDyNjLQX7E,1780
207
- deltacat-1.1.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
208
- deltacat-1.1.0.dist-info/top_level.txt,sha256=RWdIcid4Bv2i2ozLVh-70kJpyB61xEKXod9XXGpiono,9
209
- deltacat-1.1.0.dist-info/RECORD,,
205
+ deltacat-1.1.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
206
+ deltacat-1.1.1.dist-info/METADATA,sha256=XeXOc863rqN4olrgF3bK3Hm3Cozw7nlshK-hHILg-o4,1780
207
+ deltacat-1.1.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
208
+ deltacat-1.1.1.dist-info/top_level.txt,sha256=RWdIcid4Bv2i2ozLVh-70kJpyB61xEKXod9XXGpiono,9
209
+ deltacat-1.1.1.dist-info/RECORD,,