Created
May 8, 2015 13:47
-
-
Save simplyvikram/039bc181c22a0fdb4ad6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import defaultdict | |
import sys | |
class Transaction(object): | |
def __init__(self, level, parent_transaction): | |
self.level = level | |
self.parent_transaction = parent_transaction | |
self.child_transaction = None | |
self.key_val = {} | |
self.unset_keys = set() | |
self.val_count = defaultdict(int) | |
def commit(self): | |
if self.child_transaction is not None: | |
self.child_transaction.commit() | |
for key, val in self.child_transaction.key_val.iteritems(): | |
self.set_value(key, val) | |
for key in self.child_transaction.unset_keys: | |
self.unset(key) | |
self.child_transaction = None | |
def start_new_transaction(self): | |
self.child_transaction = Transaction(self.level + 1, self) | |
return self.child_transaction | |
def set_value(self, key, val): | |
self._remove_old_value(key) | |
self.key_val[key] = val | |
self.val_count[val] += 1 | |
if key in self.unset_keys: | |
self.unset_keys.remove(key) | |
def unset(self, key): | |
self._remove_old_value(key) | |
self.unset_keys.add(key) | |
def get_value(self, key): | |
val = self.key_val.get(key, None) | |
if val is not None: | |
return val | |
if key in self.unset_keys: | |
return None | |
if self.parent_transaction is not None: | |
return self.parent_transaction.get_value(key) | |
return None | |
def num_of_values(self, val): | |
counter = 0 | |
if self.parent_transaction is not None: | |
counter += self.parent_transaction.num_of_values(val) | |
counter += self.val_count.get(val, 0) | |
return counter | |
def _remove_old_value(self, key): | |
val = self.key_val.get(key) | |
if val is not None: | |
count = self.val_count.get(val, 0) | |
if count > 1: | |
self.val_count[val] -= 1 | |
else: | |
del self.val_count[val] | |
del self.key_val[key] | |
if __name__ == '__main__': | |
main_transaction = Transaction(0, None) | |
current_transaction = main_transaction | |
while True: | |
line = sys.stdin.readline().rstrip('\n') | |
if line == '': | |
continue | |
line = line.lower() | |
if line == 'begin': | |
current_transaction = current_transaction.start_new_transaction() | |
elif line == 'rollback': | |
if current_transaction != main_transaction: | |
current_transaction = current_transaction.parent_transaction | |
current_transaction.child_transaction = None | |
else: | |
sys.stdout('NO TRANSACTION\n') | |
elif line == 'commit': | |
if current_transaction != main_transaction: | |
main_transaction.commit() | |
elif line.startswith('set'): | |
_, key, val = line.split() | |
current_transaction.set_value(key, val) | |
elif line.startswith('unset'): | |
_, key = line.split() | |
current_transaction.unset(key) | |
elif line.startswith('get'): | |
_, key = line.split() | |
val = current_transaction.get_value(key) | |
s = ' ' | |
s += 'null' if val is None else val | |
s += '\n' | |
sys.stdout.write(s) | |
elif line.startswith('numequalto'): | |
_, val = line.split() | |
count = current_transaction.num_of_values(val) | |
sys.stdout.write(' ' + str(count) + '\n') | |
elif line.startswith('level'): | |
sys.stdout.write(' ' + str(current_transaction.level) + '\n') | |
elif line == "end": | |
print '-----All done----' | |
sys.exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment