view grok_interview/transaction.py @ 54:b3e82d22f961

[PostDog] Initial commit BROKEN
author June Park <parkjune1995@gmail.com>
date Fri, 19 Dec 2025 13:58:52 -0800
parents 68fa88ac73fe
children
line wrap: on
line source

# Question: In-Memory Key-Value Store with Nested Transactions
# 
# Design an in-memory key-value database that supports the following commands and fully handles nested transactions.
# Core Operations:

# SET <key> <value>: Sets the value for a key.
 
# GET <key>: Returns the value for a key.
 
# UNSET <key>: Removes the key and its value.
# 
# Transaction Operations:

# BEGIN: Starts a new transaction scope. If a transaction is already active, this starts a nested transaction.

# COMMIT: Applies all changes made in the current transaction scope and all its active nested transactions to the parent scope (or to the main database state if no parent exists). After a successful commit, the transaction scope is closed.

# ROLLBACK: Discards all changes made in the current transaction scope and all its active nested transactions, restoring the state to what it was when the BEGIN command was issued for the current scope. After a successful rollback, the transaction scope is closed.

# Implementation Goal:
# Design the primary data structures and outline the logic for SET, COMMIT, and ROLLBACK to ensure nested transactions operate correctly. Explain how the state of the database is managed across multiple transaction layers.


class Database:
    def __init__(self):
        self.global_db = {}
        self.queue = []

    def commit(self):
        copy_db = self.queue.pop()
        if self.queue:
            self.queue[-1].merge(copy_db)
        else:
            self.global_db |= copy_db

    def set(self, key, value):
        if self.queue:
            curr_db = self.queue[-1]
            curr_db[key] = value
        else:
            self.global_db[key] = value

    def get(self, key):
        if self.queue:
            for copy_db in reversed(self.queue):
                if key in copy_db:
                    return copy_db[key]

        return self.global_db[key]

    def unset(self, key):
        if self.queue:
            curr_db = self.queue[-1]
            del curr_db[key]
        else:
            del self.global_db[key]