Skip to content

Commit

Permalink
prototype of version deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
amakelov committed Aug 21, 2024
1 parent a63eafa commit d628910
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 26 deletions.
15 changes: 15 additions & 0 deletions mandala/deps/versioner.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,21 @@ def __init__(
"outputs",
]
self.df = pd.DataFrame(columns=columns)

def drop_semantic_version(self, semantic_version: str):
# drop from df
self.df = self.df[self.df["semantic_version"] != semantic_version]
# drop from .versions
for dep_key, versions in self.versions.items():
keys_to_drop = []
for k, version in versions.items():
if version.semantic_version == semantic_version:
keys_to_drop.append(k)
for k in keys_to_drop:
del versions[k]
# TODO: we should clean up more thoroughly, but this is a start
# TODO: remove from component_dags if no longer used
# TODO: remove from nodes if no longer used

def get_version_ids(
self,
Expand Down
82 changes: 56 additions & 26 deletions mandala/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,9 @@ def _get_call_from_data(self, call_data: Dict[str, Any], in_memory: bool) -> Cal
def get_call(self, hid: str, lazy: bool) -> Call:
return self.mget_call([hid], in_memory=lazy)[0]

def drop_calls(self, calls_or_hids: Union[Iterable[str], Iterable[Call]], delete_dependents: bool):
@transaction
def drop_calls(self, calls_or_hids: Union[Iterable[str], Iterable[Call]], delete_dependents: bool,
conn: Optional[sqlite3.Connection] = None):
"""
Remove the calls with the given HIDs (and optionally their dependents)
from the storage *and* the cache.
Expand All @@ -345,7 +347,7 @@ def drop_calls(self, calls_or_hids: Union[Iterable[str], Iterable[Call]], delete
hids = set(hids)
if delete_dependents:
_, dependent_call_hids = self.call_storage.get_dependents(
ref_hids=set(), call_hids=hids
ref_hids=set(), call_hids=hids, conn=conn,
)
hids |= dependent_call_hids
num_dropped_cache = 0
Expand All @@ -355,8 +357,8 @@ def drop_calls(self, calls_or_hids: Union[Iterable[str], Iterable[Call]], delete
self.call_cache.drop(hid)
num_dropped_cache += 1
for hid in hids:
if self.call_storage.exists(hid):
self.call_storage.drop(hid)
if self.call_storage.exists(hid, conn=conn):
self.call_storage.drop(hid, conn=conn)
num_dropped_persistent += 1
logger.info(f"Dropped {num_dropped_persistent} calls (and {num_dropped_cache} from cache).")

Expand Down Expand Up @@ -977,39 +979,47 @@ def _show_version_data(
@transaction
def versions(
self,
f: Union[Callable, "funcs.FuncInterface"],
meta: bool = False,
f: Op,
show_dep_commit_ids: bool = False, # show the commit ids of the dependencies
plain: bool = False,
conn: Optional[sqlite3.Connection] = None,
):
"""
Show each stored version of the `@op` together with the code/reprs of
all dependencies for this version.
"""
self._show_version_data(
f=f,
deps=True,
meta=meta,
meta=show_dep_commit_ids,
plain=plain,
compact=False,
conn=conn,
)

# @transaction
# def sources(
# self,
# f: Union[Callable, "funcs.FuncInterface"],
# meta: bool = False,
# plain: bool = False,
# compact: bool = False,
# conn: Optional[sqlite3.Connection] = None,
# ):
# func = extract_func_obj(obj=f, strict=True)
# component = get_dep_key_from_func(func=func)
# versioner = self.get_versioner(conn=conn)
# print(
# f"Revision history for the source code of function {component[1]} from module {component[0]} "
# '("===HEAD===" is the current version):'
# )
# versioner.component_dags[component].show(
# compact=compact, plain=plain, include_metadata=meta
# )
@transaction
def source_history(
self,
f: Op,
show_commit_ids: bool = False, # show the commit ids of each version
plain: bool = False,
compact: bool = False,
conn: Optional[sqlite3.Connection] = None,
):
"""
Print a tree representation of how the source code of this function
was modified over time.
"""
func = extract_func_obj(obj=f, strict=True)
component = get_dep_key_from_func(func=func)
versioner = self.get_versioner(conn=conn)
print(
f"Revision history for the source code of function {component[1]} from module {component[0]} "
'("===HEAD===" is the current version):'
)
versioner.component_dags[component].show(
compact=compact, plain=plain, include_metadata=show_commit_ids
)

@transaction
def code(
Expand Down Expand Up @@ -1062,6 +1072,26 @@ def diff(
print(
_get_colorized_diff(current=code_1, new=code_2, context_lines=context_lines)
)

@transaction
def drop_version(
self, semantic_version: str, conn: Optional[sqlite3.Connection] = None
):
"""
Does the following things:
- deletes all calls to this semantic version and their dependencies;
- deletes the semantic version from the versioner;
"""
### delete all calls first (and their dependents)
# TODO: very inefficient, we should have a DB query for this
calls_df = self.calls.persistent.get_df(conn=conn)
calls_df = calls_df.query(f'semantic_version == "{semantic_version}"')
call_hids = calls_df.index.get_level_values('call_history_id').unique()
self.drop_calls(calls_or_hids=call_hids, delete_dependents=True, conn=conn)
### remove from versioner
versioner = self.get_versioner(conn=conn)
versioner.drop_semantic_version(semantic_version=semantic_version)
self.save_versioner(versioner=versioner, conn=conn)

############################################################################
### user-facing functions
Expand Down

0 comments on commit d628910

Please sign in to comment.