-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A faster Installed-First policy #55
Changes from all commits
2e5c8b2
d480bac
c5db343
3326993
f31e69a
78933d3
2c89732
4068290
f6dce8f
ea1396b
8413695
ebf8e24
60cf276
d7ccf4f
a1e4c40
bf895b8
c2668ce
d6aae02
76a52f9
5a995fe
06c6499
4483b54
dca7a6c
b676d9c
d9e1c01
7b5b790
60587c2
6c957bf
537d39a
ac3de16
7a369b5
158c316
a20d9b0
5015ae4
1dba7bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
|
||
|
||
import six | ||
|
||
from collections import OrderedDict | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpick: let's put stdlib import first |
||
|
||
|
||
class _MISSING(object): | ||
pass | ||
MISSING = _MISSING() | ||
|
||
|
||
class AssignmentSet(object): | ||
|
||
"""A collection of literals and their assignments.""" | ||
|
||
def __init__(self, assignments=None): | ||
# Changelog is a dict of id -> (original value, new value) | ||
# FIXME: Verify that we really need ordering here | ||
self._data = OrderedDict() | ||
self._orig = {} | ||
self._cached_changelog = None | ||
self._assigned_literals = set() | ||
for k, v in (assignments or {}).items(): | ||
self[k] = v | ||
|
||
def __setitem__(self, key, value): | ||
assert key > 0 | ||
|
||
prev_value = self.get(key) | ||
|
||
if prev_value is not None: | ||
self._assigned_literals.difference_update((key, -key)) | ||
|
||
if value is not None: | ||
self._assigned_literals.add(key if value else -key) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure I understand that code: if value is not None, the if inside in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consequently, assuming the above comment is accurate, when does |
||
|
||
self._update_diff(key, value) | ||
self._data[key] = value | ||
|
||
def __delitem__(self, key): | ||
self._update_diff(key, MISSING) | ||
prev = self._data.pop(key) | ||
if prev is not None: | ||
self._assigned_literals.difference_update((key, -key)) | ||
|
||
def __getitem__(self, key): | ||
return self._data[key] | ||
|
||
def get(self, key, default=None): | ||
return self._data.get(key, default) | ||
|
||
def __len__(self): | ||
return len(self._data) | ||
|
||
def __contains__(self, key): | ||
return key in self._data | ||
|
||
def items(self): | ||
return list(self._data.items()) | ||
|
||
def iteritems(self): | ||
return six.iteritems(self._data) | ||
|
||
def keys(self): | ||
return list(self._data.keys()) | ||
|
||
def values(self): | ||
return list(self._data.values()) | ||
|
||
def _update_diff(self, key, value): | ||
prev = self._data.get(key, MISSING) | ||
self._orig.setdefault(key, prev) | ||
# If a value changes, dump the cached changelog | ||
self._cached_changelog = None | ||
|
||
def get_changelog(self): | ||
if self._cached_changelog is None: | ||
self._cached_changelog = { | ||
key: (old, new) | ||
for key, old in six.iteritems(self._orig) | ||
for new in [self._data.get(key, MISSING)] | ||
if new != old | ||
} | ||
return self._cached_changelog | ||
|
||
def consume_changelog(self): | ||
old = self.get_changelog() | ||
self._orig = {} | ||
self._cached_changelog = {} | ||
return old | ||
|
||
def copy(self): | ||
new = AssignmentSet() | ||
new._data = self._data.copy() | ||
new._orig = self._orig.copy() | ||
new._assigned_literals = self._assigned_literals.copy() | ||
return new | ||
|
||
def value(self, lit): | ||
""" Return the value of literal in terms of the positive. """ | ||
if lit in self._assigned_literals: | ||
return True | ||
elif -lit in self._assigned_literals: | ||
return False | ||
else: | ||
return None | ||
|
||
@property | ||
def num_assigned(self): | ||
return len(self._assigned_literals) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add_requirements
now implies hard requirements, not just packages we should prefer if possible. ThePolicy
gets a reference toinstalled_repository
and can figure out on its own which packages are currently installed if it wants to.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from an API POV, I wonder if it would not be simpler to remove
add_packages_by_id
altogether, and make it an implementation detail (called at creation time from a passedinstalled_repository
).