Skip to content

Instantly share code, notes, and snippets.

@simplyvikram
Created May 8, 2015 13:47
Show Gist options
  • Save simplyvikram/039bc181c22a0fdb4ad6 to your computer and use it in GitHub Desktop.
Save simplyvikram/039bc181c22a0fdb4ad6 to your computer and use it in GitHub Desktop.
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