Course contents
On this page
Lesson 06 of 59

Build the first lookup in memory

Walk through a short program that finds product 27, including the missing-product case.

We have asked SQL to find a product. Now we will implement the search directly. Start with three records in the working memory of a running program. This is small enough to inspect without a storage library or a database server.

The following Python example is complete. Python is used to make the mechanism readable; it does not choose the implementation language for our eventual engine.

products = [
    {"product_id": 12, "name": "Notebook"},
    {"product_id": 27, "name": "Canvas tote"},
    {"product_id": 46, "name": "Desk lamp"},
]

def find_product(rows, wanted_id):
    for row in rows:
        if row["product_id"] == wanted_id:
            return row
    return None

assert find_product(products, 27)["name"] == "Canvas tote"
assert find_product(products, 99) is None

Read the program one decision at a time

The outer square brackets hold a list. Each pair of braces holds a record with named fields. row["product_id"] reads that field from the current record.

def introduces a function: a named operation we can call with different inputs. Here its inputs are a collection of rows and the product number we want. The loop visits one row at a time. == tests equality. return finishes the function and supplies its answer.

  1. Inspect product 12

    12 does not equal 27. Continue.

  2. Inspect product 27

    27 equals 27. Return the Canvas tote record.

  3. Product 46 is not inspected

    The function has already returned.

A scan tests rows until it finds a match or runs out of rows.

None represents “no matching record” here. It is our function’s missing-result signal, not a SQL row containing NULL. A caller must check that signal before reading fields from the result.

The two assert lines are executable checks. They stop with an error if the result differs from our expectation. One checks a present product; the other checks an absent product. They do not prove all behavior, but they exercise two different paths.

State what this tiny function assumes

Our input has distinct product IDs and correctly shaped records. The function does not enforce those rules itself. If the list contains two records with ID 27, it returns the first one. A real table needs insertion logic that checks the key rule before accepting a duplicate.

The returned object is also the existing record, not a protected copy. Other code could change it directly. That is acceptable for this trace; it would be a poor boundary for enforcing transactions.

Try the missing case by hand

How many rows does a lookup for product 99 inspect? What happens with an empty list?

Follow the loop to its end

For 99, all three comparisons fail, so the loop finishes and the function returns None. With an empty list, the loop body never runs; execution goes straight to the same missing-result return.

The final return is necessary. A successful lookup alone would not have shown whether the function handles absence deliberately.

We have an understandable read operation. Before making it faster, we need to preserve its records after the program stops. The next stage turns those records into bytes that a file can store.

Further reading

Python’s introduction to control flow explains loops and functions. For algorithm foundations, the MIT 6.006 notes cover data structures and the work their operations perform.