diff --git a/scripts/build.py b/scripts/build.py index 5dd1d26a1..2cd36de6a 100644 --- a/scripts/build.py +++ b/scripts/build.py @@ -5,6 +5,9 @@ import markdown import logging from datetime import datetime +from urllib.parse import quote +import re +from collections import defaultdict # Set up logging logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') @@ -17,27 +20,43 @@ class Page: path: Path content: str modified_date: datetime + category: Optional[str] + tags: List[str] + description: Optional[str] is_index: bool = False class SiteGenerator: """Generates a static site from a directory of mixed content""" - MARKDOWN_EXTENSIONS = ['meta', 'toc', 'fenced_code', 'tables'] - SUPPORTED_CONTENT = {'.md'} # Expandable for future content types - IGNORED_DIRECTORIES = {'.git', '__pycache__', 'node_modules'} + MARKDOWN_EXTENSIONS = [ + 'meta', + 'toc', + 'fenced_code', + 'tables', + 'attr_list', + 'footnotes', + 'def_list', + 'admonition' + ] + SUPPORTED_CONTENT = {'.md', '.markdown'} + IGNORED_DIRECTORIES = {'.git', '__pycache__', 'node_modules', '.github', 'venv', '.venv'} def __init__(self, input_dir: str, output_dir: str): self.input_dir = Path(input_dir) self.output_dir = Path(output_dir) self.markdown_converter = markdown.Markdown(extensions=self.MARKDOWN_EXTENSIONS) self.pages: Dict[Path, Page] = {} + self.categories: Dict[str, List[Page]] = defaultdict(list) + self.tags: Dict[str, List[Page]] = defaultdict(list) def generate_site(self) -> None: """Main method to generate the static site""" try: self._prepare_output_directory() self._process_content() + self._organize_content() self._copy_assets() + self._generate_special_pages() self._generate_html_pages() logger.info(f"Site generated successfully in {self.output_dir}") except Exception as e: @@ -49,9 +68,13 @@ def _prepare_output_directory(self) -> None: if self.output_dir.exists(): shutil.rmtree(self.output_dir) self.output_dir.mkdir(parents=True) - # Set directory permissions to 755 (rwxr-xr-x) self.output_dir.chmod(0o755) + # Create assets directory + assets_dir = self.output_dir / 'assets' + assets_dir.mkdir(parents=True) + assets_dir.chmod(0o755) + def _process_content(self) -> None: """Process all content in the input directory""" for file_path in self._walk_directory(self.input_dir): @@ -67,32 +90,76 @@ def _walk_directory(self, directory: Path) -> List[Path]: files.append(item) return files + def _extract_metadata(self, file_path: Path) -> dict: + """Extract metadata from markdown file""" + content = file_path.read_text(encoding='utf-8') + self.markdown_converter.reset() + self.markdown_converter.convert(content) + + metadata = {} + if hasattr(self.markdown_converter, 'Meta'): + metadata = { + 'title': self.markdown_converter.Meta.get('title', [file_path.stem.replace('-', ' ').title()])[0], + 'category': self.markdown_converter.Meta.get('category', [None])[0], + 'tags': self.markdown_converter.Meta.get('tags', [''])[0].split(',') if 'tags' in self.markdown_converter.Meta else [], + 'description': self.markdown_converter.Meta.get('description', [None])[0] + } + else: + metadata = { + 'title': file_path.stem.replace('-', ' ').title(), + 'category': None, + 'tags': [], + 'description': None + } + + return metadata + def _process_markdown(self, file_path: Path) -> None: """Process a markdown file into a Page object""" try: content = file_path.read_text(encoding='utf-8') + metadata = self._extract_metadata(file_path) + + # Convert content after metadata extraction self.markdown_converter.reset() html_content = self.markdown_converter.convert(content) - # Get title from metadata or filename - if hasattr(self.markdown_converter, 'Meta') and 'title' in self.markdown_converter.Meta: - title = self.markdown_converter.Meta['title'][0] - else: - title = file_path.stem.replace('-', ' ').title() - relative_path = file_path.relative_to(self.input_dir) is_index = file_path.stem.lower() == 'index' - self.pages[relative_path] = Page( - title=title, + # Clean and normalize tags + tags = [tag.strip().lower() for tag in metadata['tags'] if tag.strip()] + + page = Page( + title=metadata['title'], path=relative_path, content=html_content, modified_date=datetime.fromtimestamp(file_path.stat().st_mtime), + category=metadata['category'], + tags=tags, + description=metadata['description'], is_index=is_index ) + + self.pages[relative_path] = page + + # Organize by category and tags + if page.category: + self.categories[page.category].append(page) + for tag in page.tags: + self.tags[tag].append(page) + except Exception as e: logger.error(f"Failed to process {file_path}: {str(e)}") + def _organize_content(self) -> None: + """Organize pages by category and tags""" + # Sort pages within categories and tags + for category in self.categories: + self.categories[category].sort(key=lambda p: p.title) + for tag in self.tags: + self.tags[tag].sort(key=lambda p: p.title) + def _copy_assets(self) -> None: """Copy non-markdown files to output directory""" for file_path in self._walk_directory(self.input_dir): @@ -100,25 +167,147 @@ def _copy_assets(self) -> None: relative_path = file_path.relative_to(self.input_dir) output_path = self.output_dir / relative_path output_path.parent.mkdir(parents=True, exist_ok=True) - # Set directory permissions to 755 (rwxr-xr-x) output_path.parent.chmod(0o755) shutil.copy2(file_path, output_path) - # Set file permissions to 644 (rw-r--r--) output_path.chmod(0o644) + def _generate_special_pages(self) -> None: + """Generate special pages like category index and tag index""" + # Generate categories index + if self.categories: + categories_content = self._render_categories_index() + categories_page = Page( + title="Categories", + path=Path("categories/index.md"), + content=categories_content, + modified_date=datetime.now(), + category=None, + tags=[], + description="Index of all categories", + is_index=True + ) + self.pages[categories_page.path] = categories_page + + # Generate tags index + if self.tags: + tags_content = self._render_tags_index() + tags_page = Page( + title="Tags", + path=Path("tags/index.md"), + content=tags_content, + modified_date=datetime.now(), + category=None, + tags=[], + description="Index of all tags", + is_index=True + ) + self.pages[tags_page.path] = tags_page + + def _render_categories_index(self) -> str: + """Render the categories index page""" + content = "

Categories

\n" + return content + + def _render_tags_index(self) -> str: + """Render the tags index page""" + content = "

Tags

\n" + return content + def _generate_html_pages(self) -> None: """Generate HTML pages for all processed content""" + # Generate regular pages for page in self.pages.values(): output_path = self.output_dir / page.path.with_suffix('.html') output_path.parent.mkdir(parents=True, exist_ok=True) - # Set directory permissions to 755 (rwxr-xr-x) output_path.parent.chmod(0o755) html_content = self._render_template(page) output_path.write_text(html_content, encoding='utf-8') - # Set file permissions to 644 (rw-r--r--) output_path.chmod(0o644) + # Generate category pages + for category, pages in self.categories.items(): + self._generate_category_page(category, pages) + + # Generate tag pages + for tag, pages in self.tags.items(): + self._generate_tag_page(tag, pages) + + def _generate_category_page(self, category: str, pages: List[Page]) -> None: + """Generate a page for a specific category""" + output_path = self.output_dir / 'categories' / f"{category.lower()}.html" + output_path.parent.mkdir(parents=True, exist_ok=True) + output_path.parent.chmod(0o755) + + content = f"

Category: {category}

\n" + + page = Page( + title=f"Category: {category}", + path=Path(f"categories/{category.lower()}.md"), + content=content, + modified_date=datetime.now(), + category=None, + tags=[], + description=f"Pages in category {category}", + is_index=False + ) + + html_content = self._render_template(page) + output_path.write_text(html_content, encoding='utf-8') + output_path.chmod(0o644) + + def _generate_tag_page(self, tag: str, pages: List[Page]) -> None: + """Generate a page for a specific tag""" + output_path = self.output_dir / 'tags' / f"{tag.lower()}.html" + output_path.parent.mkdir(parents=True, exist_ok=True) + output_path.parent.chmod(0o755) + + content = f"

Tag: {tag}

\n" + + page = Page( + title=f"Tag: {tag}", + path=Path(f"tags/{tag.lower()}.md"), + content=content, + modified_date=datetime.now(), + category=None, + tags=[], + description=f"Pages tagged with {tag}", + is_index=False + ) + + html_content = self._render_template(page) + output_path.write_text(html_content, encoding='utf-8') + output_path.chmod(0o644) + + def _generate_breadcrumbs(self, page: Page) -> str: + """Generate breadcrumb navigation""" + parts = [] + parts.append('Home') + + if page.category: + parts.append(f'{page.category}') + + if not page.is_index: + parts.append(page.title) + + return ' » '.join(parts) + def _generate_navigation(self, current_page: Page) -> str: """Generate navigation links""" nav_items = [] @@ -127,17 +316,28 @@ def _generate_navigation(self, current_page: Page) -> str: if not current_page.is_index: nav_items.append('Home') - # Add other pages - for page in sorted(self.pages.values(), key=lambda p: p.title): - if not page.is_index: - relative_url = f"/{page.path.with_suffix('.html')}" - nav_items.append(f'{page.title}') + # Add categories link + if self.categories: + nav_items.append('Categories') + + # Add tags link + if self.tags: + nav_items.append('Tags') return '\n'.join(nav_items) def _render_template(self, page: Page) -> str: """Render HTML template for a page""" navigation = self._generate_navigation(page) + breadcrumbs = self._generate_breadcrumbs(page) + + # Generate tags section if page has tags + tags_section = "" + if page.tags: + tags_section = "
Tags: " + ", ".join( + f'{tag}' + for tag in sorted(page.tags) + ) + "
" return f''' @@ -145,12 +345,14 @@ def _render_template(self, page: Page) -> str: {page.title} + {f'' if page.description else ''} @@ -235,13 +513,18 @@ def _render_template(self, page: Page) -> str: {navigation}
+

{page.title}

- Last modified: {page.modified_date.strftime('%Y-%m-%d')} + Last modified: {page.modified_date.strftime('%Y-%m-%d')} + {f'Category: {page.category}' if page.category else ''}
{page.content}
+ {tags_section}
''' @@ -253,8 +536,12 @@ def main(): parser = argparse.ArgumentParser(description='Generate a static site from markdown files') parser.add_argument('input_dir', help='Input directory containing content') parser.add_argument('output_dir', help='Output directory for generated site') + parser.add_argument('--verbose', '-v', action='store_true', help='Enable verbose logging') args = parser.parse_args() + if args.verbose: + logging.getLogger().setLevel(logging.DEBUG) + try: generator = SiteGenerator(args.input_dir, args.output_dir) generator.generate_site() diff --git a/site/.github/workflows/deploy.yml b/site/.github/workflows/deploy.yml deleted file mode 100644 index 64f1c873e..000000000 --- a/site/.github/workflows/deploy.yml +++ /dev/null @@ -1,23 +0,0 @@ -jobs: - # Build job - build: - # Specify runner + build & upload the static files as an artifact - runs-on: ubuntu-latest - steps: - - name: Upload static files as artifact - id: deployment - uses: actions/upload-pages-artifact@v3 # or specific "vX.X.X" version tag for this action - with: - path: site/ - - # Deployment job - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/site/CNAME b/site/CNAME deleted file mode 100644 index 39aa53ab1..000000000 --- a/site/CNAME +++ /dev/null @@ -1 +0,0 @@ -notes.elimelt.com \ No newline at end of file diff --git a/site/README.html b/site/README.html index faba50a4b..812e89398 100644 --- a/site/README.html +++ b/site/README.html @@ -4,12 +4,14 @@ Readme +
+

Readme

- Last modified: 2024-02-09 + Last modified: 2024-02-09 +

My notes for everything

This is a repo where I store my notes and resources. I write my notes in markdown with vim, and use a custom GUI to view them. Some of them are taken while reading textbooks, and others are taken in real time during lectures.

Please note that much of the info on here is paraphrased from other sources, and I claim no ownership of it. This is also a work in progress, and I am constantly adding to and editing it. If you have any questions or comments, feel free to reach out.

+
\ No newline at end of file diff --git a/site/algorithms/BFS.html b/site/algorithms/BFS.html index 32281714c..4bb170fe1 100644 --- a/site/algorithms/BFS.html +++ b/site/algorithms/BFS.html @@ -4,12 +4,14 @@ Bfs +
+

Bfs

- Last modified: 2024-04-03 + Last modified: 2024-04-03 +

Breadth First Search

@@ -327,6 +262,7 @@

Shortest paths

queue.append((neighbor, level + 1))
+
\ No newline at end of file diff --git a/site/algorithms/DAGs.html b/site/algorithms/DAGs.html index 3118c9bf3..485851aec 100644 --- a/site/algorithms/DAGs.html +++ b/site/algorithms/DAGs.html @@ -4,12 +4,14 @@ Dags +
+

Dags

- Last modified: 2024-04-14 + Last modified: 2024-04-14 +

Directed Acyclic Graphs (DAGs)

@@ -279,6 +214,7 @@

Algorithm

return order
+
\ No newline at end of file diff --git a/site/algorithms/DFS.html b/site/algorithms/DFS.html index 916a61314..1c31284f6 100644 --- a/site/algorithms/DFS.html +++ b/site/algorithms/DFS.html @@ -4,12 +4,14 @@ Dfs +
+

Dfs

- Last modified: 2024-04-13 + Last modified: 2024-04-13 +

Depth First Search (DFS)

@@ -276,6 +211,7 @@

Properties of DFS Spanning Trees

DFS visits every vertex within the starting vertex's connected component, so you can use it to find all connected components of a graph similar to BFS.

However, unlike BFS, the DFS tree has the property that every non-tree edge joins a vertex to one of its ancestors/decedents in the tree. We can thus still use DFS to find cycles in a graph.

+
\ No newline at end of file diff --git a/site/algorithms/approximation-algorithms.html b/site/algorithms/approximation-algorithms.html index 4d445ffc6..64692e491 100644 --- a/site/algorithms/approximation-algorithms.html +++ b/site/algorithms/approximation-algorithms.html @@ -4,12 +4,14 @@ Approximation Algorithms +
+

Approximation Algorithms

- Last modified: 2024-05-06 + Last modified: 2024-05-06 +

Approximation Algorithms

@@ -277,6 +212,7 @@

log(n) approximation for Set Cover

Algorithm: While there are remaining elements, choose the set that maximizes the number of new elements covered.

If the optimal solution has $k$ sets, this algorithm always selects at most $k log(n)$ sets. This is because there is at least a set that covers $\frac{1}{k}$ of the remaining elements, so after $t$ steps we have $ \le n(1 - \frac{1}{k})^t \le n \cdot e^{-\frac{t}{k}}$ remaining elements. Therefore, after $t = k\ln(n)$ steps, we have $< 1$ uncovered element remaining.

+
\ No newline at end of file diff --git a/site/algorithms/bipartite-graphs.html b/site/algorithms/bipartite-graphs.html index ebf6a5067..4413237a3 100644 --- a/site/algorithms/bipartite-graphs.html +++ b/site/algorithms/bipartite-graphs.html @@ -4,12 +4,14 @@ Bipartite Graphs +
+

Bipartite Graphs

- Last modified: 2024-04-10 + Last modified: 2024-04-10 +

Bipartite Graphs

@@ -266,6 +201,7 @@

Odd-Length Cycles

Algorithm

Problem: Given a graph $G$, output true if it is bipartite, false otherwise.

+
\ No newline at end of file diff --git a/site/algorithms/connected-components.html b/site/algorithms/connected-components.html index 3057ee895..6692c1087 100644 --- a/site/algorithms/connected-components.html +++ b/site/algorithms/connected-components.html @@ -4,12 +4,14 @@ Connected Components +
+

Connected Components

- Last modified: 2024-04-10 + Last modified: 2024-04-10 +

Connected Components

@@ -289,6 +224,7 @@

Connected Components

Strategy for Unconnected Graph

In general, if you are solving a graph problem you should first assume your graph is fully connected, and then after you've found a solution for connected graphs, you can run your algorithm on all the connected components of your graph.

+
\ No newline at end of file diff --git a/site/algorithms/divide-and-conquer.html b/site/algorithms/divide-and-conquer.html index 23232f641..013eed454 100644 --- a/site/algorithms/divide-and-conquer.html +++ b/site/algorithms/divide-and-conquer.html @@ -4,12 +4,14 @@ Divide And Conquer +
+

Divide And Conquer

- Last modified: 2024-04-25 + Last modified: 2024-04-25 +

Divide and Conquer

@@ -396,6 +331,7 @@

Implementation

+
\ No newline at end of file diff --git a/site/algorithms/dynamic-programming.html b/site/algorithms/dynamic-programming.html index bf54ab3e4..d5ca909cc 100644 --- a/site/algorithms/dynamic-programming.html +++ b/site/algorithms/dynamic-programming.html @@ -4,12 +4,14 @@ Dynamic Programming +
+

Dynamic Programming

- Last modified: 2024-05-17 + Last modified: 2024-05-17 +

Dynamic Programming

@@ -867,6 +802,7 @@

P3 - Count connected subsets of si

For each call to $f(n, k)$, we solve $k \cdot n$ subproblems, each of which take a constant time to compute given that subproblems with a $k' < k$ have already been solved. We only have this constant time computation since the number of children is at most $3$, since otherwise we would need to solve a number of subproblems exponential in the $deg(v)$ to check every subset of children to include. Therefore, each call takes $O(n)$ time.

Since we call $f(v, k)$ on all vertices in the tree, and each call takes at most $O(n)$ time (but often performs better due to memoized answers from calls on ancestors of $v$), we have an upper bound of $O(n^2)$ on computing the overall answer, which is polynomial

+
\ No newline at end of file diff --git a/site/algorithms/graphs-intro.html b/site/algorithms/graphs-intro.html index e7ee1bee1..dd6985d46 100644 --- a/site/algorithms/graphs-intro.html +++ b/site/algorithms/graphs-intro.html @@ -4,12 +4,14 @@ Graphs Intro +
+

Graphs Intro

- Last modified: 2024-04-03 + Last modified: 2024-04-03 +

Graphs Introduction

@@ -327,6 +262,7 @@

Adjacency List

+
\ No newline at end of file diff --git a/site/algorithms/greedy-algorithms.html b/site/algorithms/greedy-algorithms.html index 7d0f70c0a..82ed90bf1 100644 --- a/site/algorithms/greedy-algorithms.html +++ b/site/algorithms/greedy-algorithms.html @@ -4,12 +4,14 @@ Greedy Algorithms +
+

Greedy Algorithms

- Last modified: 2024-04-19 + Last modified: 2024-04-19 +

# Greedy Algorithms

@@ -306,6 +241,7 @@

Proof of Correctness

Since we sorted by start time, all these incompatible jobs must have started before $s(j)$, and thus we have $d$ lectures overlapping at time $s(j) + \epsilon$, so our maximum depth is $\ge d$.

Since we have that the optimal solution must schedule at least depth number of classrooms, we have that the greedy algorithm is optimal.

+
\ No newline at end of file diff --git a/site/algorithms/induction.html b/site/algorithms/induction.html index ffa7b44d5..8d7e8ac58 100644 --- a/site/algorithms/induction.html +++ b/site/algorithms/induction.html @@ -4,12 +4,14 @@ Induction +
+

Induction

- Last modified: 2024-03-27 + Last modified: 2024-03-27 +

Induction

@@ -278,6 +213,7 @@

IS

Generally

With this type of induction, start with $P(n)$, and reduce to $P(n - 1)$.

+
\ No newline at end of file diff --git a/site/algorithms/linear-programming.html b/site/algorithms/linear-programming.html index 57e598fee..4af3d6417 100644 --- a/site/algorithms/linear-programming.html +++ b/site/algorithms/linear-programming.html @@ -4,12 +4,14 @@ Linear Programming +
+

Linear Programming

- Last modified: 2024-05-25 + Last modified: 2024-05-25 +

Linear Programming

@@ -395,6 +330,7 @@

Weighted Vertex Cover

\end{array} $$

+
\ No newline at end of file diff --git a/site/algorithms/network-flows.html b/site/algorithms/network-flows.html index 4aaccee49..3d027473c 100644 --- a/site/algorithms/network-flows.html +++ b/site/algorithms/network-flows.html @@ -4,12 +4,14 @@ Network Flows +
+

Network Flows

- Last modified: 2024-05-24 + Last modified: 2024-05-24 +

Network Flow - Max Flow and Min Cut

@@ -470,6 +405,7 @@

P4 - Knights

  • $|I| \ge k$: Suppose for the sake of contradiction that $|I| < k$. Then there must exist some set of valid placements $P = (i_1, j_1), \ldots, (i_k, j_k)$ in which we can place knights such that none of the knights attack each other. By construction of $G$, we would therefore have no edges between any of the vertices corresponding to pairs in $P$, and so said vertices would form an independent set, say $I'$. Since $|I| < k$, we have $|I'| > |I|$, which is a contradiction to $I$ being a maximum independent set.
  • +
    \ No newline at end of file diff --git a/site/algorithms/patterns/BFS.html b/site/algorithms/patterns/BFS.html index a04dfc32e..b0042f99a 100644 --- a/site/algorithms/patterns/BFS.html +++ b/site/algorithms/patterns/BFS.html @@ -4,12 +4,14 @@ Bfs +
    +

    Bfs

    - Last modified: 2024-04-04 + Last modified: 2024-04-04 +

    Breadth First Search

    @@ -256,6 +191,7 @@

    Breadth First Search

    L_i = {neighbors(v_j)\ :\ v_j\ \in L_{i\ -\ 1}\setminus L_0\ \cup L_1\ \cup\ldots\cup L_{i\ -\ 2}} $$

    +
    \ No newline at end of file diff --git a/site/algorithms/patterns/sliding-window.html b/site/algorithms/patterns/sliding-window.html index 2e5f64910..6600262e0 100644 --- a/site/algorithms/patterns/sliding-window.html +++ b/site/algorithms/patterns/sliding-window.html @@ -4,12 +4,14 @@ Sliding Window +
    +

    Sliding Window

    - Last modified: 2024-03-31 + Last modified: 2024-03-31 +

    Sliding Window

    @@ -282,6 +217,7 @@

    Practice Problems

  • minimum-window-substring
  • +
    \ No newline at end of file diff --git a/site/algorithms/practice/4.html b/site/algorithms/practice/4.html index 677b60738..6f637b342 100644 --- a/site/algorithms/practice/4.html +++ b/site/algorithms/practice/4.html @@ -4,12 +4,14 @@ 4 +
    +

    4

    - Last modified: 2024-04-24 + Last modified: 2024-04-24 +

    Problem Set 4

    @@ -309,7 +244,7 @@

    Correctness: Greedy Stays Ahead

    IH: Suppose $P(k - 2)$ holds.

    IS:

    Let $A = a_1, a_2, \ldots, a_{k - 1}, a_k$ be sorted numbers. Remove $a_1$ and $a_k$ to get $A' = a_2, \ldots, a_{k - 1}$. Since $A'$ is still sorted, and has $|A'| = k - 2$, we know $P(k - 2)$ holds.

    -

    Therefore, we have $G'{max} \le X'{max}$ for $A'$.

    +

    Therefore, we have $G'{max} \le X'$ for $A'$.

    Consider an arbitrary pair chosen by $G$ on $A'$, $(a_i, a_j)$, with $a_i \le a_j$. By our sort order, we have $a_1 \le a_i \le a_j \le a_k$. Now, consider the ways we could swap elements between these two pairs

    Case 1: $a_1 + a_k > a_i + a_j$

    -

    In either of the above cases, we are increasing the max of the two sums by swapping elements, and this holds for an arbitrary $a_i, a_j$ chosen by $G'$, which is at least as good as the optimum. Since we know $X'{max} \ge G'{max}$, and also that any pairing other than the one picked by $G$ ($a_1, a_k$) leads to an increased sum, it must be the case that $G_{max} \le X_{max}$, and so $P(k)$ holds.

    +

    In either of the above cases, we are increasing the max of the two sums by swapping elements, and this holds for an arbitrary $a_i, a_j$ chosen by $G'$, which is at least as good as the optimum. Since we know $X'{max} \ge G'$, and so $P(k)$ holds.}$, and also that any pairing other than the one picked by $G$ ($a_1, a_k$) leads to an increased sum, it must be the case that $G_{max} \le X_{max

    Problem 3

    Lemma (1): For any two trees $T_1$ and $T_2$ with $v \in T_1$ and $u \in T_2$, if we add the edge $(u, v)$ between the two trees, we get a new tree $T_3$.

    Proof:

    @@ -441,6 +376,7 @@

    Correctness

    return count_interval_sums_recursive(A, I, l, u, 0, len(A))
    +
    \ No newline at end of file diff --git a/site/algorithms/problems/graphs-and-trees.html b/site/algorithms/problems/graphs-and-trees.html index bb87e3eaf..d9042a359 100644 --- a/site/algorithms/problems/graphs-and-trees.html +++ b/site/algorithms/problems/graphs-and-trees.html @@ -4,12 +4,14 @@ Graphs And Trees +
    +

    Graphs And Trees

    - Last modified: 2024-04-08 + Last modified: 2024-04-08 +

    Graphs and Trees

    @@ -272,6 +207,7 @@

    Solution

    Claim: The sum of the degrees of all vertices in a graph is equal to twice the number of edges.

    Proof: Each edge contributes $1$ to the degree of two vertices, so the sum of the degrees of all vertices is twice the number of edges.

    +
    \ No newline at end of file diff --git a/site/algorithms/runtime.html b/site/algorithms/runtime.html index bd098fc26..18173585c 100644 --- a/site/algorithms/runtime.html +++ b/site/algorithms/runtime.html @@ -4,12 +4,14 @@ Runtime +
    +

    Runtime

    - Last modified: 2024-04-01 + Last modified: 2024-04-01 +

    Measuring Efficiency

    @@ -276,6 +211,7 @@

    "Efficient" Algorithms

    A CPU typically does less than $2^30$ operations per second. For this reason, some things just aren't computable.

    Polynomial time algorithms are great, since if a problem size grows by at most a constant factor, then so does its run-time.

    +
    \ No newline at end of file diff --git a/site/algorithms/stable-matching.html b/site/algorithms/stable-matching.html index f2d0faa1f..22fb085e5 100644 --- a/site/algorithms/stable-matching.html +++ b/site/algorithms/stable-matching.html @@ -4,12 +4,14 @@ Stable Matching +
    +

    Stable Matching

    - Last modified: 2024-03-30 + Last modified: 2024-03-30 +

    Stable Matching

    @@ -314,7 +249,7 @@

    Output is always perfect:

    This means there is an applicant that was never proposed to by the unmatched company, which is a contradiction.

    Output is a stable matching

    For the sake of contradiction, suppose there exists an unstable pair not matched.

    -

    Let $S$ be the output of the GS algorithm, and $(c, a)$ to be some unstable pair. Since $S$ is perfect, there is an existing pair $(c, a') \in S$. Furthermore, since $S$ is unstable, we have that $c >{a} c'$ and $a' >{c} a$.

    +

    Let $S$ be the output of the GS algorithm, and $(c, a)$ to be some unstable pair. Since $S$ is perfect, there is an existing pair $(c, a') \in S$. Furthermore, since $S$ is unstable, we have that $c >{a} c'$ and $a' > a$.

    But $c$ must have proposed to and been rejected by $a$. Additionally, $a$ must have traded $c$ for a better company. Yet, $a$ ends up with a less preferred company, which is a contradiction.

    GS Solution Properties

    Company Optimal Assignments

    @@ -329,14 +264,14 @@

    Proof

    $$ a \in valid(c) \to \exists \text{ stable matching } S \text{ such that } (c, a) \in S $$

    -

    Say $(c', a') \in S$. If $a >{c'} a'$, then $(a, c')$ is unstable for $S$, which is a contradiction to the preceding claim. Therefore, we must have $a' >{c'} a$. This also implies that $c'$ is also rejected by $BVP(c')$, since $c'$ proposed in decreasing order of preference, so it must already be rejected by $a'$.

    +

    Say $(c', a') \in S$. If $a >{c'} a'$, then $(a, c')$ is unstable for $S$, which is a contradiction to the preceding claim. Therefore, we must have $a' > a$. This also implies that $c'$ is also rejected by $BVP(c')$, since $c'$ proposed in decreasing order of preference, so it must already be rejected by $a'$.

    We can continue the same line of reasoning since $c'$ is also rejected by $BVP(c')$, and so on. This is a contradiction because $c$ is the first company rejected by their BVP.

    Applicant Pessimality

    Claim: Each applicant receives their worst valid partner (self descriptive).

    Proof

    Let $S^$ be the output of $GS$. For cont. suppose $(c, a) \in S^$, but $c \ne WVP(a)$.

    Say $c' = WVP(a)$. Since $c' \in valid(a)$, $\exists \text{ stable matching } S$ such that $(c', a) \in S$. Further, suppose $(c, a') \in S$.

    -

    If $a >{c} a'$, then $(c, a)$ is unstable for $S$. Therefore, we must have $a' >{c} a$. If $a' >_{c} a$, then by the above prove, $a = BVP(c)$. That is a contradiction because $a'$ is also valid.

    +

    If $a >{c} a'$, then $(c, a)$ is unstable for $S$. Therefore, we must have $a' > a$, then by the above prove, $a = BVP(c)$. That is a contradiction because $a'$ is also valid.} a$. If $a' >_{c

    Efficient Implementation

    Can be implemented in $O(n^2)$ time.

    Companies are named $1, ..., n$, and students are named $n + 1, ..., 2n$. Each company has a list of preferences of students, and each student has a list of preferences of companies.

    @@ -423,6 +358,7 @@

    Does print(data[i])

    +
    \ No newline at end of file diff --git a/site/algorithms/tmp.html b/site/algorithms/tmp.html index 559c87eb0..3f30ed699 100644 --- a/site/algorithms/tmp.html +++ b/site/algorithms/tmp.html @@ -4,12 +4,14 @@ Tmp +
    +

    Tmp

    - Last modified: 2024-05-21 + Last modified: 2024-05-21 +

    1

    @@ -251,6 +186,7 @@

    1

    Each vertex is a square, and there are edges between two vertices

    Independent set problem: find the largest set of vertices such that no two vertices are connected by an edge

    +
    \ No newline at end of file diff --git a/site/algorithms/tree-intro.html b/site/algorithms/tree-intro.html index 14f892f80..30efb674c 100644 --- a/site/algorithms/tree-intro.html +++ b/site/algorithms/tree-intro.html @@ -4,12 +4,14 @@ Tree Intro +
    +

    Tree Intro

    - Last modified: 2024-04-03 + Last modified: 2024-04-03 +

    Trees

    @@ -263,6 +198,7 @@

    Properties of Trees

  • $G$ has $|V| - 1$ edges
  • +
    \ No newline at end of file diff --git a/site/cheatsheets/algorithms/divide-and-conquer.html b/site/cheatsheets/algorithms/divide-and-conquer.html index 7cc1164af..ff2d5c465 100644 --- a/site/cheatsheets/algorithms/divide-and-conquer.html +++ b/site/cheatsheets/algorithms/divide-and-conquer.html @@ -4,12 +4,14 @@ Divide And Conquer +
    +

    Divide And Conquer

    - Last modified: 2024-04-28 + Last modified: 2024-04-28 +

    Divide and Conquer

    @@ -282,6 +217,7 @@

    kth Smallest Element

  • Else, recurse on $f(S_{>}, k - |S_{<}| - |S_{=}|)$
  • +
    \ No newline at end of file diff --git a/site/cheatsheets/algorithms/graphs.html b/site/cheatsheets/algorithms/graphs.html index 0031115b8..7a8596bf6 100644 --- a/site/cheatsheets/algorithms/graphs.html +++ b/site/cheatsheets/algorithms/graphs.html @@ -4,12 +4,14 @@ Graphs +
    +

    Graphs

    - Last modified: 2024-04-28 + Last modified: 2024-04-28 +

    Graphs

    @@ -332,6 +267,7 @@

    Disjoint Sets

  • If the label of a root is $k$, there are at least $2^k$ elements in the set.
  • +
    \ No newline at end of file diff --git a/site/cheatsheets/algorithms/intervals.html b/site/cheatsheets/algorithms/intervals.html index 6944d6a86..6768bc822 100644 --- a/site/cheatsheets/algorithms/intervals.html +++ b/site/cheatsheets/algorithms/intervals.html @@ -4,12 +4,14 @@ Intervals +
    +

    Intervals

    - Last modified: 2024-04-28 + Last modified: 2024-04-28 +

    Interval Scheduling/Partitioning

    @@ -269,6 +204,7 @@

    Partitioning int
  • Since we sorted by start time, all intervals $I_j \in S_1 \cup \ldots \cup S_{d - 1}$ have $s(I_i) \ge s(I_j)$. Thus, we have at least depth $d$ intervals, and so all valid partitions must have $\ge d$ sets.
  • +
    \ No newline at end of file diff --git a/site/cheatsheets/circuits/components.html b/site/cheatsheets/circuits/components.html index 49a72aaf2..d04af1446 100644 --- a/site/cheatsheets/circuits/components.html +++ b/site/cheatsheets/circuits/components.html @@ -4,12 +4,14 @@ Components +
    +

    Components

    - Last modified: 2024-03-12 + Last modified: 2024-03-12 +

    Component Dictionary

    @@ -403,6 +338,7 @@

    Rules (ideal negative feedback n

    Non-Ideal Op-Amps

    In practice, real Op-Amps have two additional terminals for a positive supply and ground (or negative supply). The output voltage is limited to the range between the positive and negative supply voltages. The gain is limited by this maximum output voltage.

    +
    \ No newline at end of file diff --git a/site/cheatsheets/circuits/electricity.html b/site/cheatsheets/circuits/electricity.html index 3507f9a8b..a54cd698d 100644 --- a/site/cheatsheets/circuits/electricity.html +++ b/site/cheatsheets/circuits/electricity.html @@ -4,12 +4,14 @@ Electricity +
    +

    Electricity

    - Last modified: 2024-03-11 + Last modified: 2024-03-11 +

    Electricity Basics

    @@ -304,6 +239,7 @@

    Parallel

    +---O---+
    +
    \ No newline at end of file diff --git a/site/cheatsheets/java-spring-boot/reference.html b/site/cheatsheets/java-spring-boot/reference.html index c327501f0..4dfe5e1ea 100644 --- a/site/cheatsheets/java-spring-boot/reference.html +++ b/site/cheatsheets/java-spring-boot/reference.html @@ -4,12 +4,14 @@ Reference +
    +

    Reference

    - Last modified: 2023-12-21 + Last modified: 2023-12-21 +

    Annotations and their meanings

    @@ -264,6 +199,7 @@

    Annotations and their meanings

    used to bind the web request parameter to a method parameter.
    +
    \ No newline at end of file diff --git a/site/cheatsheets/java-spring-boot/running.html b/site/cheatsheets/java-spring-boot/running.html index ee087d7fe..7ea23d488 100644 --- a/site/cheatsheets/java-spring-boot/running.html +++ b/site/cheatsheets/java-spring-boot/running.html @@ -4,12 +4,14 @@ Running +
    +

    Running

    - Last modified: 2023-12-21 + Last modified: 2023-12-21 +

    Quickstart

    @@ -267,6 +202,7 @@

    Deploying the application

    cp build/libs/<JAR_NAME>.jar <DEPLOYMENT_DIRECTORY>
    +
    \ No newline at end of file diff --git a/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch1-reliable-scalable-and-maintainable-applications.html b/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch1-reliable-scalable-and-maintainable-applications.html index d850ee89d..29dd8829c 100644 --- a/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch1-reliable-scalable-and-maintainable-applications.html +++ b/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch1-reliable-scalable-and-maintainable-applications.html @@ -4,12 +4,14 @@ Ch1 Reliable Scalable And Maintainable Applications +
    +

    Ch1 Reliable Scalable And Maintainable Applications

    - Last modified: 2023-12-26 + Last modified: 2023-12-26 +

    Chapter 1

    @@ -296,6 +231,7 @@

    Maintainability

    Simplicity: make it easy for new engineers to understand the system, by removing as much complexity as possible from the system. Manage complexity with abstraction.

    Evolvability: make it easy for engineers to make changes to the system in the future, adapting it for unanticipated use cases as requirements change. Good abstractions and modularity allow components to be replaced, and the overall system architecture to be modified, without complete reimplementation.

    +
    \ No newline at end of file diff --git a/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch2-data-models-and-query-languages.html b/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch2-data-models-and-query-languages.html index e7a0faca2..49b0a777c 100644 --- a/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch2-data-models-and-query-languages.html +++ b/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch2-data-models-and-query-languages.html @@ -4,12 +4,14 @@ Ch2 Data Models And Query Languages +
    +

    Ch2 Data Models And Query Languages

    - Last modified: 2024-01-19 + Last modified: 2024-01-19 +

    Chapter 2

    @@ -407,6 +342,7 @@

    Triple-Stores and SPARQL

    Consists of three-part statements of the form (subject, predicate, object). The subject and object are vertices, and the predicate is an edge.

    ```sql

    +
    \ No newline at end of file diff --git a/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch3-storage-and-retrieval.html b/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch3-storage-and-retrieval.html index 47e53cdbd..4b52f7c74 100644 --- a/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch3-storage-and-retrieval.html +++ b/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch3-storage-and-retrieval.html @@ -4,12 +4,14 @@ Ch3 Storage And Retrieval +
    +

    Ch3 Storage And Retrieval

    - Last modified: 2024-02-10 + Last modified: 2024-02-10 +

    Chapter 3

    @@ -341,6 +276,7 @@

    Aggregation: Data Cubes a

    Data cubes are a way to precompute aggregations over multiple dimensions. They are good for speeding up queries, but can be expensive to maintain. Essentially a multi-dimensional array, where each cell is an aggregation over a subset of the dimensions. Very expensive to maintain, and inflexible for queries that aren't covered by the precomputed aggregations.

    Oftentimes, it makes more sense to store raw data, and then benchmark queries to see which ones are slow, and then precompute aggregations for those queries if they need to be faster.

    +
    \ No newline at end of file diff --git a/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch4-encoding-and-evolution.html b/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch4-encoding-and-evolution.html index 27e479272..b81490765 100644 --- a/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch4-encoding-and-evolution.html +++ b/site/designing-data-intensive-applications/part-1-foundations-of-data-systems/ch4-encoding-and-evolution.html @@ -4,12 +4,14 @@ Ch4 Encoding And Evolution +
    +

    Ch4 Encoding And Evolution

    - Last modified: 2024-01-18 + Last modified: 2024-01-18 +

    Chapter 4

    @@ -344,6 +279,7 @@

    Distributed Actor Frameworks

  • Erlang OTP experimental support for mapping Erlang data types to protobuf. Still need to be careful about schema evolution.
  • +
    \ No newline at end of file diff --git a/site/designing-data-intensive-applications/part-2-distributed-data/ch5-replication.html b/site/designing-data-intensive-applications/part-2-distributed-data/ch5-replication.html index 78d07373d..e77c0e801 100644 --- a/site/designing-data-intensive-applications/part-2-distributed-data/ch5-replication.html +++ b/site/designing-data-intensive-applications/part-2-distributed-data/ch5-replication.html @@ -4,12 +4,14 @@ Ch5 Replication +
    +

    Ch5 Replication

    - Last modified: 2023-12-31 + Last modified: 2023-12-31 +

    Chapter 5

    @@ -318,6 +253,7 @@

    Logical (row-based) log replicationWith multi-row transactions, log contains entry for all rows, as well as entry for transaction commit (MySQL binlog uses this approach)

    Logical logs decouple the replication from the storage engine, allowing better compatibility between versions. Also allows integrations with external services (e.g. Kafka, Elasticsearch, etc.)

    +
    \ No newline at end of file diff --git a/site/designing-data-intensive-applications/part-2-distributed-data/preface.html b/site/designing-data-intensive-applications/part-2-distributed-data/preface.html index e5fbc18a2..a84e2458f 100644 --- a/site/designing-data-intensive-applications/part-2-distributed-data/preface.html +++ b/site/designing-data-intensive-applications/part-2-distributed-data/preface.html @@ -4,12 +4,14 @@ Preface +
    +

    Preface

    - Last modified: 2023-12-26 + Last modified: 2023-12-26 +

    Preface

    @@ -261,6 +196,7 @@

    Scaling Out

    Shared Nothing Architecture is a multi machine setup with each machine having its own CPU, memory, and disk. This is the most scalable, but it requires a lot of coordination between machines. Each machine (or VM) is a node, and each node is completely independent. Inter-node communication is done over the network through software.

    For the remainder of this part (Part 2), we will be focusing on shared nothing architectures.

    +
    \ No newline at end of file diff --git a/site/designing-data-intensive-applications/part-3-derived-data/ch10-batch-processing.html b/site/designing-data-intensive-applications/part-3-derived-data/ch10-batch-processing.html index ba8eff6c4..7aa71d535 100644 --- a/site/designing-data-intensive-applications/part-3-derived-data/ch10-batch-processing.html +++ b/site/designing-data-intensive-applications/part-3-derived-data/ch10-batch-processing.html @@ -4,12 +4,14 @@ Ch10 Batch Processing +
    +

    Ch10 Batch Processing

    - Last modified: 2023-12-23 + Last modified: 2023-12-23 +

    Chapter 10

    @@ -402,6 +337,7 @@

    Output of Batch Workflows

    return result
    +
    \ No newline at end of file diff --git a/site/digital-design/combinational-logic.html b/site/digital-design/combinational-logic.html index b03aafd12..a76c3cad8 100644 --- a/site/digital-design/combinational-logic.html +++ b/site/digital-design/combinational-logic.html @@ -4,12 +4,14 @@ Combinational Logic +
    +

    Combinational Logic

    - Last modified: 2024-03-26 + Last modified: 2024-03-26 +

    Combinational Logic

    @@ -377,6 +312,7 @@

    DeMorgan's Law

    $$

    In a circuit, the more general rule is that if you have an AND or OR gate with some inverted terminals, to apply demorgans law, you just change the type of gate (ie AND to OR or OR to AND) and invert the inputs (ie change all the points that are inverted to not inverted and vice versa).

    +
    \ No newline at end of file diff --git a/site/digital-design/karnaugh-maps.html b/site/digital-design/karnaugh-maps.html index ba4eb02b7..89bfd1a89 100644 --- a/site/digital-design/karnaugh-maps.html +++ b/site/digital-design/karnaugh-maps.html @@ -4,12 +4,14 @@ Karnaugh Maps +
    +

    Karnaugh Maps

    - Last modified: 2024-04-09 + Last modified: 2024-04-09 +

    Karnaugh Maps

    @@ -272,6 +207,7 @@

    Procedural Blocks

  • always_comb: like always @ (*), but only triggered when any of the signals change.
  • +
    \ No newline at end of file diff --git a/site/digital-design/quartus-workflow.html b/site/digital-design/quartus-workflow.html index fe9f31a8b..8d0926ab2 100644 --- a/site/digital-design/quartus-workflow.html +++ b/site/digital-design/quartus-workflow.html @@ -4,12 +4,14 @@ Quartus Workflow +
    +

    Quartus Workflow

    - Last modified: 2024-04-25 + Last modified: 2024-04-25 +
    +
    \ No newline at end of file diff --git a/site/digital-design/sequential-logic.html b/site/digital-design/sequential-logic.html index 23171fc02..69ce3a5f9 100644 --- a/site/digital-design/sequential-logic.html +++ b/site/digital-design/sequential-logic.html @@ -4,12 +4,14 @@ Sequential Logic +
    +

    Sequential Logic

    - Last modified: 2024-05-14 + Last modified: 2024-05-14 +

    Sequential Logic (SL)

    @@ -274,6 +209,7 @@

    Maximum Clock Frequency

    max_delay = max(clock_to_q + max_cl_delay, max_cl_delay)

    Then, min_period = max_delay + t_setup, and max_freq = 1/min_period.

    +
    \ No newline at end of file diff --git a/site/digital-design/system-verilog.html b/site/digital-design/system-verilog.html index 18b19ab73..88221e9cf 100644 --- a/site/digital-design/system-verilog.html +++ b/site/digital-design/system-verilog.html @@ -4,12 +4,14 @@ System Verilog +
    +

    System Verilog

    - Last modified: 2024-04-02 + Last modified: 2024-04-02 +

    SystemVerilog

    @@ -338,6 +273,7 @@

    2-input MUX

    endmodule
    +
    \ No newline at end of file diff --git a/site/digital-design/waveform-diagram.html b/site/digital-design/waveform-diagram.html index 87c1d819e..af2d06057 100644 --- a/site/digital-design/waveform-diagram.html +++ b/site/digital-design/waveform-diagram.html @@ -4,12 +4,14 @@ Waveform Diagram +
    +

    Waveform Diagram

    - Last modified: 2024-04-02 + Last modified: 2024-04-02 +

    Waveform Diagrams

    @@ -287,6 +222,7 @@

    Test Benches

    endmodule // MUX2_tb
    +
    \ No newline at end of file diff --git a/site/distributed-systems/RPC.html b/site/distributed-systems/RPC.html index 29ed85c2d..be7efbf35 100644 --- a/site/distributed-systems/RPC.html +++ b/site/distributed-systems/RPC.html @@ -4,12 +4,14 @@ Rpc +
    +

    Rpc

    - Last modified: 2024-03-27 + Last modified: 2024-03-27 +

    Look Into

    @@ -389,6 +324,7 @@

    Two Generals Problem

    Just a thought experiment to emphasize the difficulty of message passing in a distributed system. Two generals are trying to coordinate an attack on a city. They are separated by a valley, and can only communicate by messenger. The messenger can be captured by the city, and the generals don't know if the message was delivered. The generals need to agree on a time to attack, but they can't be sure the message was delivered. They can only attack if they both agree on the time.

    The problem boils down to the fact that at any point in time, if we sent a message, we don't know if it was delivered. Regardless of how many round trips you make to confirm, the last message sent could always have been dropped. This is a fundamental and central problem in distributed systems.

    +
    \ No newline at end of file diff --git a/site/distributed-systems/bigtable.html b/site/distributed-systems/bigtable.html index e6065e960..ec7600f2a 100644 --- a/site/distributed-systems/bigtable.html +++ b/site/distributed-systems/bigtable.html @@ -4,12 +4,14 @@ Bigtable +
    +

    Bigtable

    - Last modified: 2024-05-17 + Last modified: 2024-05-17 +

    Bigtable: A Distributed Storage System for Structured Data

    @@ -358,6 +293,7 @@

    Google Earth

    The preprocessing pipeline uses one table to store raw image data (with compression turned off since it is handled manually). During preprocessing, the images are cleaned and consolidated into the final serving data. Each row in the preprocessing table corresponds to a single geographic segment, and rows are named so that adjacent geographic segments are stored near eachother. This preprocessing pipeline relies heavily on MapReduce over Bigtable.

    The serving system uses a single table to index data stored in GFS. Although its relatively small (500 GB), it serves tens of thousands of queries per second, so it is hosted on hundreds of tablet servers to load balance, each containing in-memory column families.

    +
    \ No newline at end of file diff --git a/site/distributed-systems/clocks.html b/site/distributed-systems/clocks.html index 944aefc14..548d562c9 100644 --- a/site/distributed-systems/clocks.html +++ b/site/distributed-systems/clocks.html @@ -4,12 +4,14 @@ Clocks +
    +

    Clocks

    - Last modified: 2024-04-14 + Last modified: 2024-04-14 +

    Clocks

    @@ -345,6 +280,7 @@

    Algorithm

    }
    +
    \ No newline at end of file diff --git a/site/distributed-systems/consistency.html b/site/distributed-systems/consistency.html index 8defc83b6..9c201eb30 100644 --- a/site/distributed-systems/consistency.html +++ b/site/distributed-systems/consistency.html @@ -4,12 +4,14 @@ Consistency +
    +

    Consistency

    - Last modified: 2024-05-12 + Last modified: 2024-05-12 +

    Consistency

    @@ -375,6 +310,7 @@

    Memory Barrier/Fence

    This is how POSIX files work. Also many mutli-cache systems use fences to enforce consistency.

    +
    \ No newline at end of file diff --git a/site/distributed-systems/consistent-global-state.html b/site/distributed-systems/consistent-global-state.html index ee9c4bc67..b4625d796 100644 --- a/site/distributed-systems/consistent-global-state.html +++ b/site/distributed-systems/consistent-global-state.html @@ -4,12 +4,14 @@ Consistent Global State +
    +

    Consistent Global State

    - Last modified: 2024-04-13 + Last modified: 2024-04-13 +

    Consistent Global State in Distributed Systems

    @@ -257,6 +192,7 @@

    Asynchronous Distributed Systems

    Distributed Computations

    A distributed computation is the execution of a distributed program over a collection of processes, each of which sequentially process a stream of events. Particularly, for two nodes to communicate, a message $m$ is enqueued on a channel via $send(m)$, and the message is dequeued via $receive(m)$. There is an obvious relationship between the happening of event $send(m)$ at process $p$, and the happening of event $receive(m)$ at process $q$, such that we can be sure $send(m)$ happened before $receive(m)$.

    +
    \ No newline at end of file diff --git a/site/distributed-systems/disconnected-operation.html b/site/distributed-systems/disconnected-operation.html index 1e360c368..9eb32e02d 100644 --- a/site/distributed-systems/disconnected-operation.html +++ b/site/distributed-systems/disconnected-operation.html @@ -4,12 +4,14 @@ Disconnected Operation +
    +

    Disconnected Operation

    - Last modified: 2024-12-08 + Last modified: 2024-12-08 +

    Disconnected Operation

    @@ -282,6 +217,7 @@

    Merge Strategies

  • Operation based: Changes are represented as operations (add, delete, etc.) and are applied in order. This is how CRDTs work.
  • +
    \ No newline at end of file diff --git a/site/distributed-systems/distributed-cache-coherence.html b/site/distributed-systems/distributed-cache-coherence.html index fc96f1e5b..b3b486ce6 100644 --- a/site/distributed-systems/distributed-cache-coherence.html +++ b/site/distributed-systems/distributed-cache-coherence.html @@ -4,12 +4,14 @@ Distributed Cache Coherence +
    +

    Distributed Cache Coherence

    - Last modified: 2024-05-17 + Last modified: 2024-05-17 +

    Distributed Cache Coherence

    @@ -334,6 +269,7 @@

    Write Back Cache Coherence

  • e.g. if primary fails, backup can take over by replaying log
  • +
    \ No newline at end of file diff --git a/site/distributed-systems/dynamo-db.html b/site/distributed-systems/dynamo-db.html index 0b186b5a6..cabd7f7ad 100644 --- a/site/distributed-systems/dynamo-db.html +++ b/site/distributed-systems/dynamo-db.html @@ -4,12 +4,14 @@ Dynamo Db +
    +

    Dynamo Db

    - Last modified: 2024-05-24 + Last modified: 2024-05-24 +

    Dynamo: Amazon's Highly Available Key-value Store

    reading

    Dynamo is a highly available key-value storage system that sacrifices consistency under certain failure conditions, making extensive use of object versioning and application assisted conflict resolution.

    +
    \ No newline at end of file diff --git a/site/distributed-systems/google-file-system.html b/site/distributed-systems/google-file-system.html index 74bb2cc16..e62aa097b 100644 --- a/site/distributed-systems/google-file-system.html +++ b/site/distributed-systems/google-file-system.html @@ -4,12 +4,14 @@ Google File System +
    +

    Google File System

    - Last modified: 2024-05-21 + Last modified: 2024-05-21 +

    Google File System (GFS)

    @@ -342,6 +277,7 @@

    Lease and Mutation Order

  • The primary replies to the client, and any errors are reported to the client. Errors leave the region in an inconsistent state, but the failed mutation is usually retried multiple times, until eventually falling back to redoing the entire write.
  • +
    \ No newline at end of file diff --git a/site/distributed-systems/load-balancing.html b/site/distributed-systems/load-balancing.html index 00e902a5f..232aaf345 100644 --- a/site/distributed-systems/load-balancing.html +++ b/site/distributed-systems/load-balancing.html @@ -4,12 +4,14 @@ Load Balancing +
    +

    Load Balancing

    - Last modified: 2024-05-06 + Last modified: 2024-05-06 +

    Load Balancing

    @@ -280,6 +215,7 @@

    Key Popularity

    We can cope with popular keys using power of two choices. Keys can be hashed to multiple (in this case two, but generalizes to $k$) servers, and requests are forwarded to whichever server is under less load.

    +
    \ No newline at end of file diff --git a/site/distributed-systems/managing-critical-state.html b/site/distributed-systems/managing-critical-state.html index eecf38513..b441237d7 100644 --- a/site/distributed-systems/managing-critical-state.html +++ b/site/distributed-systems/managing-critical-state.html @@ -4,12 +4,14 @@ Managing Critical State +
    +

    Managing Critical State

    - Last modified: 2024-04-04 + Last modified: 2024-04-04 +

    Managing Critical State

    @@ -311,6 +246,7 @@

    Distributed Consensus Performance

    One common performance pitfall with single-leader replication is that a client's perceived latency is proportional to the round-trip time between the client and the leader.

    Multi-Paxos: Detailed Message Flow

    +
    \ No newline at end of file diff --git a/site/distributed-systems/mutual-exclusion.html b/site/distributed-systems/mutual-exclusion.html index ee90d2a0c..798abb364 100644 --- a/site/distributed-systems/mutual-exclusion.html +++ b/site/distributed-systems/mutual-exclusion.html @@ -4,12 +4,14 @@ Mutual Exclusion +
    +

    Mutual Exclusion

    - Last modified: 2024-04-15 + Last modified: 2024-04-15 +

    Distributed Mutual Exclusion

    @@ -284,6 +219,7 @@

    Implementation

  • so request is the earliest in the queue
  • +
    \ No newline at end of file diff --git a/site/distributed-systems/non-blocking-two-phase-commit.html b/site/distributed-systems/non-blocking-two-phase-commit.html index e3c12333e..48c874dab 100644 --- a/site/distributed-systems/non-blocking-two-phase-commit.html +++ b/site/distributed-systems/non-blocking-two-phase-commit.html @@ -4,12 +4,14 @@ Non Blocking Two Phase Commit +
    +

    Non Blocking Two Phase Commit

    - Last modified: 2024-05-11 + Last modified: 2024-05-11 +

    Non-Blocking Two Phase Commit

    @@ -291,6 +226,7 @@

    Google's Bigtable in Retrospect

    Jeff Dean of Google said that not supporting distributed transactions was the biggest mistake in the the design of Bigtable. Incremental updates make it a very important feature, so users really wanted them and often tried to implement it themselves on top of Bigtable

    Spanner, Google's multi-datacenter KV store uses 2PC over Paxos, and is one of the backbones of Google's ad service.

    +
    \ No newline at end of file diff --git a/site/distributed-systems/ordering-events-in-distributed-systems.html b/site/distributed-systems/ordering-events-in-distributed-systems.html index ab2450a10..581b6ebf3 100644 --- a/site/distributed-systems/ordering-events-in-distributed-systems.html +++ b/site/distributed-systems/ordering-events-in-distributed-systems.html @@ -4,12 +4,14 @@ Ordering Events In Distributed Systems +
    +

    Ordering Events In Distributed Systems

    - Last modified: 2024-04-07 + Last modified: 2024-04-07 +

    Time, Clocks, and the Ordering of Events in a Distributed System

    @@ -346,6 +281,7 @@

    Clock Synchronization Algorithm

  • If $P_i$ sends a message $,$ at physical time $t$, then $m$ contains a timestamp $T_m = C_i(t)$. Upon receiving a message $m$ at physical time $t'$, $P_j$ sets $C_j(t') = \max(\lim_{\delta \to 0} C_j(t' - \delta), T_m + \mu_m)$.
  • +
    \ No newline at end of file diff --git a/site/distributed-systems/paxos-architecture.html b/site/distributed-systems/paxos-architecture.html index eab5b5c97..cf18b14cc 100644 --- a/site/distributed-systems/paxos-architecture.html +++ b/site/distributed-systems/paxos-architecture.html @@ -4,12 +4,14 @@ Paxos Architecture +
    +

    Paxos Architecture

    - Last modified: 2024-05-16 + Last modified: 2024-05-16 +

    Distributed Architectures with Paxos

    @@ -262,6 +197,7 @@

    Paxos as a Lease Server

    This design pattern is used in BigTable, Chubby, and ZooKeeper. It prevents split brain if the clock drift is within epsilon. We also only need to service reads on the primary, including logic for cache invalidation. Additionally, we can use write ahead logging, and instead of explicitly maintaining a backup, just replace the primary by executing the log on a new primary.

    +
    \ No newline at end of file diff --git a/site/distributed-systems/paxos-intro.html b/site/distributed-systems/paxos-intro.html index 2e71761ec..799addf4b 100644 --- a/site/distributed-systems/paxos-intro.html +++ b/site/distributed-systems/paxos-intro.html @@ -4,12 +4,14 @@ Paxos Intro +
    +

    Paxos Intro

    - Last modified: 2024-04-24 + Last modified: 2024-04-24 +

    Paxos Introduction

    @@ -277,6 +212,7 @@

    Phase 2: Accept

  • If a majority of acceptors respond, the proposal is chosen.
  • +
    \ No newline at end of file diff --git a/site/distributed-systems/paxos-made-simple.html b/site/distributed-systems/paxos-made-simple.html index 7ef119571..a0b0a2fe1 100644 --- a/site/distributed-systems/paxos-made-simple.html +++ b/site/distributed-systems/paxos-made-simple.html @@ -4,12 +4,14 @@ Paxos Made Simple +
    +

    Paxos Made Simple

    - Last modified: 2024-04-24 + Last modified: 2024-04-24 +

    Paxos Made Simple

    @@ -319,6 +254,7 @@

    Implementing a State Machine

    Once a leader has finished phase 1 for all commands thus far and afterwards, it only needs to complete phase 2 for each subsequent command requested, which is known to be the minimal algorithm for reaching consensus after phase 1.

    To reiterate what was stated previously, in the case where a single leader is not elected, progress is not guaranteed, but safety is.

    +
    \ No newline at end of file diff --git a/site/distributed-systems/primary-backup.html b/site/distributed-systems/primary-backup.html index 30dbd58bc..ba23cb840 100644 --- a/site/distributed-systems/primary-backup.html +++ b/site/distributed-systems/primary-backup.html @@ -4,12 +4,14 @@ Primary Backup +
    +

    Primary Backup

    - Last modified: 2024-04-01 + Last modified: 2024-04-01 +

    Primary Backup

    @@ -322,6 +257,7 @@

    Rules

  • Every operation must be before or after state transfers (not during).
  • +
    \ No newline at end of file diff --git a/site/distributed-systems/scaling-web-services.html b/site/distributed-systems/scaling-web-services.html index 647c53e57..f68251cec 100644 --- a/site/distributed-systems/scaling-web-services.html +++ b/site/distributed-systems/scaling-web-services.html @@ -4,12 +4,14 @@ Scaling Web Services +
    +

    Scaling Web Services

    - Last modified: 2024-04-25 + Last modified: 2024-04-25 +

    Scaling Web Services with Distributed Architectures

    @@ -270,6 +205,7 @@

    Microservices

    Organize complex distributed applications as a large number of independent services communicating through RPC, each using primary/backup or paxos for high availability and fault tolerance.

    This allows for independent development of components of a larger system, where each component can scale independently.

    +
    \ No newline at end of file diff --git a/site/distributed-systems/sharding.html b/site/distributed-systems/sharding.html index 71c5764ba..a7753a187 100644 --- a/site/distributed-systems/sharding.html +++ b/site/distributed-systems/sharding.html @@ -4,12 +4,14 @@ Sharding +
    +

    Sharding

    - Last modified: 2024-05-06 + Last modified: 2024-05-06 +

    Sharding

    @@ -257,6 +192,7 @@

    Consistent Hashing

    Indirection Tables

    A cooler approach in my opinion. Just put a table of hash(key) -> server address on every client, and assign fewer table entries to buckets with more keys. This way, the load is more evenly distributed. You can then broadcast any changes to the table to every client server.

    +
    \ No newline at end of file diff --git a/site/distributed-systems/two-phase-commit.html b/site/distributed-systems/two-phase-commit.html index 924b47bb6..cec72f0e4 100644 --- a/site/distributed-systems/two-phase-commit.html +++ b/site/distributed-systems/two-phase-commit.html @@ -4,12 +4,14 @@ Two Phase Commit +
    +

    Two Phase Commit

    - Last modified: 2024-05-11 + Last modified: 2024-05-11 +

    Two Phase Commit

    @@ -328,6 +263,7 @@

    Messages

  • Abort: abort the transaction
  • +
    \ No newline at end of file diff --git a/site/ds-backup/RPC.html b/site/ds-backup/RPC.html index e6b4c9500..3b0878e11 100644 --- a/site/ds-backup/RPC.html +++ b/site/ds-backup/RPC.html @@ -4,12 +4,14 @@ Rpc +
    +

    Rpc

    - Last modified: 2024-04-27 + Last modified: 2024-04-27 +

    Look Into

    @@ -389,6 +324,7 @@

    Two Generals Problem

    Just a thought experiment to emphasize the difficulty of message passing in a distributed system. Two generals are trying to coordinate an attack on a city. They are separated by a valley, and can only communicate by messenger. The messenger can be captured by the city, and the generals don't know if the message was delivered. The generals need to agree on a time to attack, but they can't be sure the message was delivered. They can only attack if they both agree on the time.

    The problem boils down to the fact that at any point in time, if we sent a message, we don't know if it was delivered. Regardless of how many round trips you make to confirm, the last message sent could always have been dropped. This is a fundamental and central problem in distributed systems.

    +
    \ No newline at end of file diff --git a/site/ds-backup/clocks.html b/site/ds-backup/clocks.html index 6ab7e1cd3..dd6936434 100644 --- a/site/ds-backup/clocks.html +++ b/site/ds-backup/clocks.html @@ -4,12 +4,14 @@ Clocks +
    +

    Clocks

    - Last modified: 2024-04-27 + Last modified: 2024-04-27 +

    Clocks

    @@ -345,6 +280,7 @@

    Algorithm

    }
    +
    \ No newline at end of file diff --git a/site/ds-backup/consistent-global-state.html b/site/ds-backup/consistent-global-state.html index a0759cd21..f2ee4bebe 100644 --- a/site/ds-backup/consistent-global-state.html +++ b/site/ds-backup/consistent-global-state.html @@ -4,12 +4,14 @@ Consistent Global State +
    +

    Consistent Global State

    - Last modified: 2024-04-27 + Last modified: 2024-04-27 +

    Consistent Global State in Distributed Systems

    @@ -257,6 +192,7 @@

    Asynchronous Distributed Systems

    Distributed Computations

    A distributed computation is the execution of a distributed program over a collection of processes, each of which sequentially process a stream of events. Particularly, for two nodes to communicate, a message $m$ is enqueued on a channel via $send(m)$, and the message is dequeued via $receive(m)$. There is an obvious relationship between the happening of event $send(m)$ at process $p$, and the happening of event $receive(m)$ at process $q$, such that we can be sure $send(m)$ happened before $receive(m)$.

    +
    \ No newline at end of file diff --git a/site/ds-backup/managing-critical-state.html b/site/ds-backup/managing-critical-state.html index 2a68a251a..7e18dbe48 100644 --- a/site/ds-backup/managing-critical-state.html +++ b/site/ds-backup/managing-critical-state.html @@ -4,12 +4,14 @@ Managing Critical State +
    +

    Managing Critical State

    - Last modified: 2024-04-27 + Last modified: 2024-04-27 +

    Managing Critical State

    @@ -311,6 +246,7 @@

    Distributed Consensus Performance

    One common performance pitfall with single-leader replication is that a client's perceived latency is proportional to the round-trip time between the client and the leader.

    Multi-Paxos: Detailed Message Flow

    +
    \ No newline at end of file diff --git a/site/ds-backup/mutual-exclusion.html b/site/ds-backup/mutual-exclusion.html index 5036d876b..625b18c8d 100644 --- a/site/ds-backup/mutual-exclusion.html +++ b/site/ds-backup/mutual-exclusion.html @@ -4,12 +4,14 @@ Mutual Exclusion +
    +

    Mutual Exclusion

    - Last modified: 2024-04-27 + Last modified: 2024-04-27 +

    Distributed Mutual Exclusion

    @@ -284,6 +219,7 @@

    Implementation

  • so request is the earliest in the queue
  • +
    \ No newline at end of file diff --git a/site/ds-backup/ordering-events-in-distributed-systems.html b/site/ds-backup/ordering-events-in-distributed-systems.html index 2565ec522..9e117f002 100644 --- a/site/ds-backup/ordering-events-in-distributed-systems.html +++ b/site/ds-backup/ordering-events-in-distributed-systems.html @@ -4,12 +4,14 @@ Ordering Events In Distributed Systems +
    +

    Ordering Events In Distributed Systems

    - Last modified: 2024-04-27 + Last modified: 2024-04-27 +

    Time, Clocks, and the Ordering of Events in a Distributed System

    @@ -346,6 +281,7 @@

    Clock Synchronization Algorithm

  • If $P_i$ sends a message $,$ at physical time $t$, then $m$ contains a timestamp $T_m = C_i(t)$. Upon receiving a message $m$ at physical time $t'$, $P_j$ sets $C_j(t') = \max(\lim_{\delta \to 0} C_j(t' - \delta), T_m + \mu_m)$.
  • +
    \ No newline at end of file diff --git a/site/ds-backup/paxos-intro.html b/site/ds-backup/paxos-intro.html index 643693d07..22d446232 100644 --- a/site/ds-backup/paxos-intro.html +++ b/site/ds-backup/paxos-intro.html @@ -4,12 +4,14 @@ Paxos Intro +
    +

    Paxos Intro

    - Last modified: 2024-04-27 + Last modified: 2024-04-27 +

    Paxos Introduction

    @@ -277,6 +212,7 @@

    Phase 2: Accept

  • If a majority of acceptors respond, the proposal is chosen.
  • +
    \ No newline at end of file diff --git a/site/ds-backup/paxos-made-simple.html b/site/ds-backup/paxos-made-simple.html index 6dc65e8ea..d831a41c1 100644 --- a/site/ds-backup/paxos-made-simple.html +++ b/site/ds-backup/paxos-made-simple.html @@ -4,12 +4,14 @@ Paxos Made Simple +
    +

    Paxos Made Simple

    - Last modified: 2024-04-27 + Last modified: 2024-04-27 +

    Paxos Made Simple

    @@ -319,6 +254,7 @@

    Implementing a State Machine

    Once a leader has finished phase 1 for all commands thus far and afterwards, it only needs to complete phase 2 for each subsequent command requested, which is known to be the minimal algorithm for reaching consensus after phase 1.

    To reiterate what was stated previously, in the case where a single leader is not elected, progress is not guaranteed, but safety is.

    +
    \ No newline at end of file diff --git a/site/ds-backup/primary-backup.html b/site/ds-backup/primary-backup.html index f3d08f1f3..ba4b128c2 100644 --- a/site/ds-backup/primary-backup.html +++ b/site/ds-backup/primary-backup.html @@ -4,12 +4,14 @@ Primary Backup +
    +

    Primary Backup

    - Last modified: 2024-04-27 + Last modified: 2024-04-27 +

    Primary Backup

    @@ -322,6 +257,7 @@

    Rules

  • Every operation must be before or after state transfers (not during).
  • +
    \ No newline at end of file diff --git a/site/ds-backup/scaling-web-services.html b/site/ds-backup/scaling-web-services.html index 36fbf098e..a85282f6c 100644 --- a/site/ds-backup/scaling-web-services.html +++ b/site/ds-backup/scaling-web-services.html @@ -4,12 +4,14 @@ Scaling Web Services +
    +

    Scaling Web Services

    - Last modified: 2024-04-27 + Last modified: 2024-04-27 +

    Scaling Web Services with Distributed Architectures

    @@ -270,6 +205,7 @@

    Microservices

    Organize complex distributed applications as a large number of independent services communicating through RPC, each using primary/backup or paxos for high availability and fault tolerance.

    This allows for independent development of components of a larger system, where each component can scale independently.

    +
    \ No newline at end of file diff --git a/site/linear-algebra/cheatsheet.html b/site/linear-algebra/cheatsheet.html index 7886572bf..2bd665e0f 100644 --- a/site/linear-algebra/cheatsheet.html +++ b/site/linear-algebra/cheatsheet.html @@ -4,12 +4,14 @@ Cheatsheet +
    +

    Cheatsheet

    - Last modified: 2024-11-09 + Last modified: 2024-11-09 +

    Fundamentals of Vectors

    @@ -478,19 +413,19 @@

    Basic Matrix Operations

    Addition and Subtraction

    Scalar Multiplication

    Transpose

    +
    \ No newline at end of file diff --git a/site/networks/3-network/routing.html b/site/networks/3-network/routing.html index 0dc27b737..d43e8bba8 100644 --- a/site/networks/3-network/routing.html +++ b/site/networks/3-network/routing.html @@ -4,12 +4,14 @@ Routing +
    +

    Routing

    - Last modified: 2024-03-07 + Last modified: 2024-03-07 +

    @@ -419,6 +354,7 @@

    Metrics

    The ARPANET tested different approaches to link-cost calculation. The original metric measured queued packets on each link, but it didn't consider bandwidth or latency. A later version used delay as a measure of load, taking into account link bandwidth and latency. However, it suffered from instability under heavy load and had a large range of link values. A third approach compressed the metric range, accounted for link type, and smoothed the variation over time.

    In real-world network deployments, metrics change rarely, if at all, and only under the control of a network administrator. Static metrics are the norm, with a common approach being to use a constant multiplied by (1/link_bandwidth).

    +
    \ No newline at end of file diff --git a/site/networks/4-transport/ACK-clocking.html b/site/networks/4-transport/ACK-clocking.html index da9bcb5a1..46b761551 100644 --- a/site/networks/4-transport/ACK-clocking.html +++ b/site/networks/4-transport/ACK-clocking.html @@ -4,12 +4,14 @@ Ack Clocking +
    +

    Ack Clocking

    - Last modified: 2024-02-24 + Last modified: 2024-02-24 +

    ACK Clocking

    @@ -260,6 +195,7 @@

    Problem at the Receiver

    Sliding window has pipelining to keep network busy, but what if the receiver is overloaded?

    Consider receiver with $w$ buffers. Application should recv to accept packets, but if it didn't, then

    +
    \ No newline at end of file diff --git a/site/networks/4-transport/TCP.html b/site/networks/4-transport/TCP.html index 3b7c5c32a..a228d414d 100644 --- a/site/networks/4-transport/TCP.html +++ b/site/networks/4-transport/TCP.html @@ -4,12 +4,14 @@ Tcp +
    +

    Tcp

    - Last modified: 2024-03-04 + Last modified: 2024-03-04 +

    Transmission Control Protocol (TCP)

    @@ -396,6 +331,7 @@

    Explicit Congestion Notification (

    Random Early Detection (RED)

    Instead of marking pakets, just randomly drop packets to throttle senders. The probablity of dropping a packet increases as the queue fills up.

    +
    \ No newline at end of file diff --git a/site/networks/4-transport/UDP.html b/site/networks/4-transport/UDP.html index fb956e12c..afb3ed954 100644 --- a/site/networks/4-transport/UDP.html +++ b/site/networks/4-transport/UDP.html @@ -4,12 +4,14 @@ Udp +
    +

    Udp

    - Last modified: 2024-02-23 + Last modified: 2024-02-23 +
    +
    \ No newline at end of file diff --git a/site/networks/4-transport/flow-control.html b/site/networks/4-transport/flow-control.html index 9b4ba98a3..31f2a32d3 100644 --- a/site/networks/4-transport/flow-control.html +++ b/site/networks/4-transport/flow-control.html @@ -4,12 +4,14 @@ Flow Control +
    +

    Flow Control

    - Last modified: 2024-02-24 + Last modified: 2024-02-24 +

    Flow Control

    @@ -271,6 +206,7 @@

    Selective Repeat ARQ

    Sequence Numbers

    For stop and wait, only need 0/1. For selective repeat, need $w$ numbers for packets, and $w$ numbers for acks of earlier packets. ($2w$ in total). For go-back-n, need $w$ numbers for packets, and 1 number for the ack of the last packet. ($w + 1$ in total).

    +
    \ No newline at end of file diff --git a/site/networks/4-transport/transport-overview.html b/site/networks/4-transport/transport-overview.html index 9f00b4061..55e4ff3c2 100644 --- a/site/networks/4-transport/transport-overview.html +++ b/site/networks/4-transport/transport-overview.html @@ -4,12 +4,14 @@ Transport Overview +
    +

    Transport Overview

    - Last modified: 2024-02-24 + Last modified: 2024-02-24 +

    Transport Layer Overview

    The transport layer provides end-to-end connectivity accross the network. Segments carry application data, which are carried within packets, which are carried within frames.

    The two main services are messages (datagram, UDP) and bytestreams (streams, TCP). Messages are discrete units of data, while bytestreams are continuous streams of data.

    +
    \ No newline at end of file diff --git a/site/networks/5-application/CDNs.html b/site/networks/5-application/CDNs.html index f1880480d..68c469537 100644 --- a/site/networks/5-application/CDNs.html +++ b/site/networks/5-application/CDNs.html @@ -4,12 +4,14 @@ Cdns +
    +

    Cdns

    - Last modified: 2024-03-05 + Last modified: 2024-03-05 +

    Content Delivery Networks (CDNs)

    @@ -257,6 +192,7 @@

    Content Delivery Networks (CDNs)

    A CDN is a system of distributed servers that deliver web content to a user based on the geographic locations of the user. Each region will have a number of edge locations, which are data centers that cache the content of the main server.

    The DNS resolution of a CDN URL will direct the user to the nearest edge location, which will then deliver the cached content. This process reduces the load on the original server and speeds up the delivery of the content to the user.

    +
    \ No newline at end of file diff --git a/site/networks/5-application/DNS.html b/site/networks/5-application/DNS.html index da30f8abb..09a8f4044 100644 --- a/site/networks/5-application/DNS.html +++ b/site/networks/5-application/DNS.html @@ -4,12 +4,14 @@ Dns +
    +

    Dns

    - Last modified: 2024-03-05 + Last modified: 2024-03-05 +

    Domain Name System (DNS)

    @@ -295,6 +230,7 @@

    DNS Protocol

    Servers can be replicated to handle load and reliability. Queries can return multiple records, and the client can choose which one to use.

    Security is a major concern for DNS. DNSSEC is a suite of extensions that add security to the DNS protocol by signing DNS data, but it is not widely adopted.

    +
    \ No newline at end of file diff --git a/site/networks/5-application/HTTP.html b/site/networks/5-application/HTTP.html index e769a4fa2..0cbb7a887 100644 --- a/site/networks/5-application/HTTP.html +++ b/site/networks/5-application/HTTP.html @@ -4,12 +4,14 @@ Http +
    +

    Http

    - Last modified: 2024-03-05 + Last modified: 2024-03-05 +

    Hyper Text Transfer Protocol (HTTP)

    @@ -376,6 +311,7 @@

    HTTP Caching and Proxies

    This places an intermediary between the pool of clients and the server, which can be useful for load balancing, security, and privacy. Has the added benefit of being able to improve physical locality of data to be closer to clients while in the cache. Benefits are limited by secure/dynamic content, and the "long tail" of resources that are rarely accessed.

    +
    \ No newline at end of file diff --git a/site/networks/5-application/overview.html b/site/networks/5-application/overview.html index 9a824e62b..4062371b0 100644 --- a/site/networks/5-application/overview.html +++ b/site/networks/5-application/overview.html @@ -4,12 +4,14 @@ Overview +
    +

    Overview

    - Last modified: 2024-03-01 + Last modified: 2024-03-01 +

    Application Layer Overview

    Applications built upon TCP have the benefit of being able to transfer arbitrary length data. Also provides reliability and flow control. However, some applications may not require these features and may be better suited to use UDP. Some applications even need to use UDP because they can't handle the overhead of TCP (like skype or online gaming).

    +
    \ No newline at end of file diff --git a/site/networks/reference.html b/site/networks/reference.html index 8f8c634c0..5319f0052 100644 --- a/site/networks/reference.html +++ b/site/networks/reference.html @@ -4,12 +4,14 @@ Reference +
    +

    Reference

    - Last modified: 2024-03-25 + Last modified: 2024-03-25 +

    Textbook

    @@ -251,6 +186,7 @@

    Textbook

  • computer networks, a systems approach
  • +
    \ No newline at end of file diff --git a/site/networks/sockets.html b/site/networks/sockets.html index e30728bc5..d8acd9288 100644 --- a/site/networks/sockets.html +++ b/site/networks/sockets.html @@ -4,12 +4,14 @@ Sockets +
    +

    Sockets

    - Last modified: 2024-01-11 + Last modified: 2024-01-11 +

    Socket Reference

    @@ -572,6 +507,7 @@

    Simple Server

    clientsock.close()
    +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/components.html b/site/operating-systems/lecture-notes/components.html index 618abc1a1..0c0b1a891 100644 --- a/site/operating-systems/lecture-notes/components.html +++ b/site/operating-systems/lecture-notes/components.html @@ -4,12 +4,14 @@ Components +
    +

    Components

    - Last modified: 2024-01-12 + Last modified: 2024-01-12 +

    Components of an OS

    @@ -341,6 +276,7 @@

    Microkernels

    Probably slower than monolithic kernel because of all the expensive context switches.

    +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/file-systems.html b/site/operating-systems/lecture-notes/file-systems.html index 085a10208..481b95861 100644 --- a/site/operating-systems/lecture-notes/file-systems.html +++ b/site/operating-systems/lecture-notes/file-systems.html @@ -4,12 +4,14 @@ File Systems +
    +

    File Systems

    - Last modified: 2024-02-28 + Last modified: 2024-02-28 +

    File Systems

    @@ -332,6 +267,7 @@

    FAT File System

    +-----------------+-----------------+-----------------+-----------------+
    +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/handle-tables.html b/site/operating-systems/lecture-notes/handle-tables.html index 348fb8d43..e25e67167 100644 --- a/site/operating-systems/lecture-notes/handle-tables.html +++ b/site/operating-systems/lecture-notes/handle-tables.html @@ -4,12 +4,14 @@ Handle Tables +
    +

    Handle Tables

    - Last modified: 2024-02-25 + Last modified: 2024-02-25 +

    Handle Tables

    @@ -277,6 +212,7 @@

    Making Creation Faster

    the older (now uncommon) way to do it. Instead of making a new child address space being a copy, just point to the parent address space from the child. This was an unenforced "promise" that the child wouldn't modify the address space. The child has the same page table and everything.

    method 2: copy on write.

    +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/io-systems-secondary-storage.html b/site/operating-systems/lecture-notes/io-systems-secondary-storage.html index bb483c15e..12fcd96cc 100644 --- a/site/operating-systems/lecture-notes/io-systems-secondary-storage.html +++ b/site/operating-systems/lecture-notes/io-systems-secondary-storage.html @@ -4,12 +4,14 @@ Io Systems Secondary Storage +
    +

    Io Systems Secondary Storage

    - Last modified: 2024-02-26 + Last modified: 2024-02-26 +

    I/O Systems and Secondary Storage

    @@ -347,6 +282,7 @@

    Disks and the OS

    Performance Issues

    The HDD's performance is affected by its mechanically moving parts. Limiting the amount of seeking and defragmenting help, but only to an extent.

    +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/kernel-abstraction.html b/site/operating-systems/lecture-notes/kernel-abstraction.html index e142b7307..c5dd97e9e 100644 --- a/site/operating-systems/lecture-notes/kernel-abstraction.html +++ b/site/operating-systems/lecture-notes/kernel-abstraction.html @@ -4,12 +4,14 @@ Kernel Abstraction +
    +

    Kernel Abstraction

    - Last modified: 2024-01-18 + Last modified: 2024-01-18 +

    Lecture 2 -

    @@ -260,6 +195,7 @@

    Challenge: Protection with Restr

    On x86, mode stored in EFLAGS register. On MIPS, mode stored in status register.

    +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/page-faults.html b/site/operating-systems/lecture-notes/page-faults.html index 795e72403..5c60b4390 100644 --- a/site/operating-systems/lecture-notes/page-faults.html +++ b/site/operating-systems/lecture-notes/page-faults.html @@ -4,12 +4,14 @@ Page Faults +
    +

    Page Faults

    - Last modified: 2024-02-16 + Last modified: 2024-02-16 +

    Page Fautls

    @@ -328,6 +263,7 @@

    Other Alternatives

    +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/paging.html b/site/operating-systems/lecture-notes/paging.html index fb5639813..9458ec26d 100644 --- a/site/operating-systems/lecture-notes/paging.html +++ b/site/operating-systems/lecture-notes/paging.html @@ -4,12 +4,14 @@ Paging +
    +

    Paging

    - Last modified: 2024-02-14 + Last modified: 2024-02-14 +

    Virtual Memory and Paging

    @@ -422,6 +357,7 @@

    Hard vs Soft Page Faults

  • Soft page fault: when a page is not in memory, but the OS can find it in the page file, and bring it into memory without reading from the backend storage
  • +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/processes.html b/site/operating-systems/lecture-notes/processes.html index cf6eba574..08b41cacc 100644 --- a/site/operating-systems/lecture-notes/processes.html +++ b/site/operating-systems/lecture-notes/processes.html @@ -4,12 +4,14 @@ Processes +
    +

    Processes

    - Last modified: 2024-01-12 + Last modified: 2024-01-12 +

    Processes

    @@ -292,6 +227,7 @@

    OS Process Namespace

  • Operations on processes take pid as an argument (e.g. kill)
  • +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/tlb.html b/site/operating-systems/lecture-notes/tlb.html index 21eb791f8..42fc6c71e 100644 --- a/site/operating-systems/lecture-notes/tlb.html +++ b/site/operating-systems/lecture-notes/tlb.html @@ -4,12 +4,14 @@ Tlb +
    +

    Tlb

    - Last modified: 2024-02-16 + Last modified: 2024-02-16 +

    Translation Lookaside Buffer (TLB)

    @@ -291,6 +226,7 @@

    Memory Mapped Files

    Soft Page Faults

    Fault on a page that are actually in memory, but the PTE was marked as invalid. Resolving soft faults is relatively cheap. This can be used whenever you need to wake up the OS to do something on reference to a page (for instance, a debugger watch point). Windows uses soft faults in its page replacement strategy.

    +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/windows-memory-management.html b/site/operating-systems/lecture-notes/windows-memory-management.html index e5717b661..d9f7a7b5d 100644 --- a/site/operating-systems/lecture-notes/windows-memory-management.html +++ b/site/operating-systems/lecture-notes/windows-memory-management.html @@ -4,12 +4,14 @@ Windows Memory Management +
    +

    Windows Memory Management

    - Last modified: 2024-02-21 + Last modified: 2024-02-21 +

    Windows Memory Management

    @@ -267,6 +202,7 @@

    An Interesting Exam Question fro
    int access(int* arr, int size, int stride);
     

    +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/windows-objects-handles-refcounts.html b/site/operating-systems/lecture-notes/windows-objects-handles-refcounts.html index adc5806d1..68be7ddc9 100644 --- a/site/operating-systems/lecture-notes/windows-objects-handles-refcounts.html +++ b/site/operating-systems/lecture-notes/windows-objects-handles-refcounts.html @@ -4,12 +4,14 @@ Windows Objects Handles Refcounts +
    +

    Windows Objects Handles Refcounts

    - Last modified: 2024-01-19 + Last modified: 2024-01-19 +

    Obects Handles and Reference Counts

    @@ -252,6 +187,7 @@

    Object Manager

    For example, there were objects for threads, processes, files, semaphores, etc.

    Each object had a handle count, the number of handles the user has to the object, and the ref count, the number of references to the object within the kernel (which also includes handles).

    +
    \ No newline at end of file diff --git a/site/operating-systems/lecture-notes/windows-rtz.html b/site/operating-systems/lecture-notes/windows-rtz.html index 9d0eecc0b..a85cd2f83 100644 --- a/site/operating-systems/lecture-notes/windows-rtz.html +++ b/site/operating-systems/lecture-notes/windows-rtz.html @@ -4,12 +4,14 @@ Windows Rtz +
    +

    Windows Rtz

    - Last modified: 2024-02-09 + Last modified: 2024-02-09 +

    Hard Lessons Learned: Windows RtlZeroMemory

    @@ -270,6 +205,7 @@

    Moral of the Story

  • Unfortunately, bugs in your code are sometimes actually bugs elsewhere, but that won't stop you from being assigned with finding the bug yourself.
  • +
    \ No newline at end of file diff --git a/site/operating-systems/reference.html b/site/operating-systems/reference.html index 4ef24d737..44013f689 100644 --- a/site/operating-systems/reference.html +++ b/site/operating-systems/reference.html @@ -4,12 +4,14 @@ Reference +
    +

    Reference

    - Last modified: 2024-03-25 + Last modified: 2024-03-25 +

    Textbook

    @@ -254,6 +189,7 @@

    Textbook

  • volume 4, persistent storage
  • +
    \ No newline at end of file diff --git a/site/operating-systems/section-notes/lab-3-questions.html b/site/operating-systems/section-notes/lab-3-questions.html index 9c8eaa941..eb8644e37 100644 --- a/site/operating-systems/section-notes/lab-3-questions.html +++ b/site/operating-systems/section-notes/lab-3-questions.html @@ -4,12 +4,14 @@ Lab 3 Questions +
    +

    Lab 3 Questions

    - Last modified: 2024-02-21 + Last modified: 2024-02-21 +

    Lab 3 Questions

    @@ -304,6 +239,7 @@

    Debugging

  • infinite loop on above line with addr == 24
  • +
    \ No newline at end of file diff --git a/site/operating-systems/section-notes/section-1.html b/site/operating-systems/section-notes/section-1.html index c80f2e6c9..7656f4dff 100644 --- a/site/operating-systems/section-notes/section-1.html +++ b/site/operating-systems/section-notes/section-1.html @@ -4,12 +4,14 @@ Section 1 +
    +

    Section 1

    - Last modified: 2024-01-18 + Last modified: 2024-01-18 +

    Section 1 - C and GDB review

    @@ -279,6 +214,7 @@

    GDB Review

    p <opt> <arg>: print arg

    `x : dereference and print arg

    +
    \ No newline at end of file diff --git a/site/operating-systems/v1-kernels-and-processes/1-introductions.html b/site/operating-systems/v1-kernels-and-processes/1-introductions.html index f3fa260ae..9a2b8d312 100644 --- a/site/operating-systems/v1-kernels-and-processes/1-introductions.html +++ b/site/operating-systems/v1-kernels-and-processes/1-introductions.html @@ -4,12 +4,14 @@ 1 Introductions +
    +

    1 Introductions

    - Last modified: 2024-01-12 + Last modified: 2024-01-12 +

    Introduction

    @@ -421,6 +356,7 @@

    13. For the computer you are currently using, how should the operating system designers prioritize among reliability, security, portability, performance, and adoption? Explain why.

    As a user of a macbook pro, security, performance, and adoption are extremely important. However, as a developer it would be nice to also have a portable and (less importantly) a reliable system. Something that I think the OS designers were less concerned about is portability (Apple hardware only), but this is also a question of adoption of the Sillicon based chips in Apple's hardware.

    +
    \ No newline at end of file diff --git a/site/operating-systems/v1-kernels-and-processes/2-the-kernel-abstraction.html b/site/operating-systems/v1-kernels-and-processes/2-the-kernel-abstraction.html index 2628ecc0b..d3b47d0be 100644 --- a/site/operating-systems/v1-kernels-and-processes/2-the-kernel-abstraction.html +++ b/site/operating-systems/v1-kernels-and-processes/2-the-kernel-abstraction.html @@ -4,12 +4,14 @@ 2 The Kernel Abstraction +
    +

    2 The Kernel Abstraction

    - Last modified: 2024-01-14 + Last modified: 2024-01-14 +

    Chapter 2 - The Kernel Abstraction

    @@ -667,6 +602,7 @@

    Exercises

  • Writing a program to test the operating system's protection against rogue system calls involves trying various illegal calls and observing the system's response to ensure it handles them correctly.
  • +
    \ No newline at end of file diff --git a/site/operating-systems/v1-kernels-and-processes/3-the-programming-interface.html b/site/operating-systems/v1-kernels-and-processes/3-the-programming-interface.html index 8c72c8c5c..562dff652 100644 --- a/site/operating-systems/v1-kernels-and-processes/3-the-programming-interface.html +++ b/site/operating-systems/v1-kernels-and-processes/3-the-programming-interface.html @@ -4,12 +4,14 @@ 3 The Programming Interface +
    +

    3 The Programming Interface

    - Last modified: 2024-01-14 + Last modified: 2024-01-14 +

    Chapter 3 - The Programming Interface

    @@ -741,6 +676,7 @@

    Exercises

  • Extend the shell implemented above to support foreground and background tasks, as well as job control: suspend, resume, and kill.
  • +
    \ No newline at end of file diff --git a/site/operating-systems/v2-concurrency/4-concurrency-and-threads.html b/site/operating-systems/v2-concurrency/4-concurrency-and-threads.html index 81948e879..9aec93152 100644 --- a/site/operating-systems/v2-concurrency/4-concurrency-and-threads.html +++ b/site/operating-systems/v2-concurrency/4-concurrency-and-threads.html @@ -4,12 +4,14 @@ 4 Concurrency And Threads +
    +

    4 Concurrency And Threads

    - Last modified: 2024-02-18 + Last modified: 2024-02-18 +

    Chapter 4: Concurrency and Threads

    @@ -639,6 +574,7 @@

    Data Parallel Programming

    This is useful in a wide variety of areas, and is often a source of major optimizations within programs. For instance, SQL databases can take in a query and then identify which parts of the query can be parallelized, leading to a significant speedup. This is also often used in combination with specialized hardware, like GPUs. Multimedia streaming, for example, uses SIMD instructions to decode and encode video.

    A large scale example of this is the MapReduce programming model, which is used by Google and Hadoop. The idea is to split a large dataset into smaller pieces, and then apply a function to each piece in parallel. The results are then combined together.

    +
    \ No newline at end of file diff --git a/site/operating-systems/v2-concurrency/5-synchronizing-access-to-shared-objects.html b/site/operating-systems/v2-concurrency/5-synchronizing-access-to-shared-objects.html index e227d9f44..5c3d2a086 100644 --- a/site/operating-systems/v2-concurrency/5-synchronizing-access-to-shared-objects.html +++ b/site/operating-systems/v2-concurrency/5-synchronizing-access-to-shared-objects.html @@ -4,12 +4,14 @@ 5 Synchronizing Access To Shared Objects +
    +

    5 Synchronizing Access To Shared Objects

    - Last modified: 2024-02-25 + Last modified: 2024-02-25 +

    Synchronizing Access to Shared Objects

    @@ -509,6 +444,7 @@

    Queuing Locks

    Condition Variables

    Condition variables are used to wait for a particular condition to become true. They are used in conjunction with locks to provide a way for a thread to be woken up when a condition becomes true. The condition variable is associated with a lock, and the lock must be held when waiting on the condition variable.

    +
    \ No newline at end of file diff --git a/site/operating-systems/v2-concurrency/7-multiprocessor-scheduling.html b/site/operating-systems/v2-concurrency/7-multiprocessor-scheduling.html index 603534bba..7bcb3ad88 100644 --- a/site/operating-systems/v2-concurrency/7-multiprocessor-scheduling.html +++ b/site/operating-systems/v2-concurrency/7-multiprocessor-scheduling.html @@ -4,12 +4,14 @@ 7 Multiprocessor Scheduling +
    +

    7 Multiprocessor Scheduling

    - Last modified: 2024-03-05 + Last modified: 2024-03-05 +

    Multiprocessor Scheduling

    @@ -281,6 +216,7 @@

    Real Time Scheduling

  • Priority Donation: priority inversion can lead to infinite waiting times for lower priority tasks. To avoid this, when a high-priority task is waiting for a lock held by a lower priority task, the higher priority task "dontates" some of its priority to the lower priority task. This allows the low priority task to be scheduled to complete the critical section and release the lock, at which point it will return to its original priority and the processor can be given to the high priority task.
  • +
    \ No newline at end of file diff --git a/site/operating-systems/v2-concurrency/7-queueing-theory.html b/site/operating-systems/v2-concurrency/7-queueing-theory.html index db6488857..aa1c448b0 100644 --- a/site/operating-systems/v2-concurrency/7-queueing-theory.html +++ b/site/operating-systems/v2-concurrency/7-queueing-theory.html @@ -4,12 +4,14 @@ 7 Queueing Theory +
    +

    7 Queueing Theory

    - Last modified: 2024-03-06 + Last modified: 2024-03-06 +

    Queueing Theory

    @@ -331,6 +266,7 @@

    Exponential Arrivals

    $$

    This shows the exponential relationship between response time and utilization. As utilization increases, response time increases very slowly at first, but then increases rapidly as the system approaches overload.

    +
    \ No newline at end of file diff --git a/site/operating-systems/v2-concurrency/7-uniprocessor-scheduling.html b/site/operating-systems/v2-concurrency/7-uniprocessor-scheduling.html index 018eb3d1c..d8e17703d 100644 --- a/site/operating-systems/v2-concurrency/7-uniprocessor-scheduling.html +++ b/site/operating-systems/v2-concurrency/7-uniprocessor-scheduling.html @@ -4,12 +4,14 @@ 7 Uniprocessor Scheduling +
    +

    7 Uniprocessor Scheduling

    - Last modified: 2024-03-04 + Last modified: 2024-03-04 +

    Uniprocessor Scheduling

    @@ -372,6 +307,7 @@

    MLFQ Algorithm

    Tasks are initially placed in the highest priority queue. If a task uses its entire time quantum, it is demoted to the next lower priority queue. If a task uses less than its entire time quantum, it is either kept in the same queue or moved up. This is a form of SJF within each queue.

    To prevent starvation and achieve max-min fairness, the scheduler monitors process execution time on the CPU. The scheduler then only schedules processes that have yet to recieve their fair share. If a process already got its fair share of the CPU, it is demoted to a lower priority, and if they've yet to get their fair share, they are promoted to a higher priority.

    +
    \ No newline at end of file diff --git a/site/operating-systems/v4-persistent-storage/11-file-systems-overview.html b/site/operating-systems/v4-persistent-storage/11-file-systems-overview.html index 9585a607c..045d6ee0f 100644 --- a/site/operating-systems/v4-persistent-storage/11-file-systems-overview.html +++ b/site/operating-systems/v4-persistent-storage/11-file-systems-overview.html @@ -4,12 +4,14 @@ 11 File Systems Overview +
    +

    11 File Systems Overview

    - Last modified: 2024-02-25 + Last modified: 2024-02-25 +

    File Systems: Introduction and Overview

    @@ -275,6 +210,7 @@

    Volumes

    A volume is a collection of physical storage resources that form a logical storage device. In the simplest case, a volume is a single disk. However, a disk can be partitioned into multiple volumes, and a single volume can be made of multiple disks.

    +
    \ No newline at end of file diff --git a/site/operating-systems/v4-persistent-storage/13-files-and-directories.html b/site/operating-systems/v4-persistent-storage/13-files-and-directories.html index e08aa6060..e80ae2f01 100644 --- a/site/operating-systems/v4-persistent-storage/13-files-and-directories.html +++ b/site/operating-systems/v4-persistent-storage/13-files-and-directories.html @@ -4,12 +4,14 @@ 13 Files And Directories +
    +

    13 Files And Directories

    - Last modified: 2024-01-07 + Last modified: 2024-01-07 +

    Chapter 13 - Files and Directories

    @@ -320,6 +255,7 @@

    FAT

    NTFS: Uses a tree-based structure that is more flexible than FFS's indexing scheme. Indexes variable sized extents* indead of individual blocks. NTFS is still used in Windows, and its techniques are used in many other modern file systems (ext4, XFS, HFS, HFS+).

    ZFS: Uses copy-on-write, writing new versions of files to free disk space instead of overwriting old versions. This optimizes for reliability and write performance

    +
    \ No newline at end of file diff --git a/site/performance-engineering/efficiently-implementing-state-pattern-JVM.html b/site/performance-engineering/efficiently-implementing-state-pattern-JVM.html index 896d2c632..a3be93a90 100644 --- a/site/performance-engineering/efficiently-implementing-state-pattern-JVM.html +++ b/site/performance-engineering/efficiently-implementing-state-pattern-JVM.html @@ -4,12 +4,14 @@ Efficiently Implementing State Pattern Jvm +
    +

    Efficiently Implementing State Pattern Jvm

    - Last modified: 2024-12-08 + Last modified: 2024-12-08 +

    JVM Performance with State Pattern Optimizations

    @@ -390,6 +325,7 @@

    Code Blocks to Test Performance

    Conclusion

    The low-level optimizations in InlineStatePattern using enums make it ideal for performance-critical, low-contention use cases. PolymorphicStatePattern, with its AtomicReference, offers better safety for concurrent environments but incurs a trade-off in performance due to CAS operations. Testing under these scenarios confirms that the right implementation depends on your application’s specific threading needs.

    +
    \ No newline at end of file diff --git a/site/scripts/build.py b/site/scripts/build.py index 5dd1d26a1..2cd36de6a 100644 --- a/site/scripts/build.py +++ b/site/scripts/build.py @@ -5,6 +5,9 @@ import markdown import logging from datetime import datetime +from urllib.parse import quote +import re +from collections import defaultdict # Set up logging logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') @@ -17,27 +20,43 @@ class Page: path: Path content: str modified_date: datetime + category: Optional[str] + tags: List[str] + description: Optional[str] is_index: bool = False class SiteGenerator: """Generates a static site from a directory of mixed content""" - MARKDOWN_EXTENSIONS = ['meta', 'toc', 'fenced_code', 'tables'] - SUPPORTED_CONTENT = {'.md'} # Expandable for future content types - IGNORED_DIRECTORIES = {'.git', '__pycache__', 'node_modules'} + MARKDOWN_EXTENSIONS = [ + 'meta', + 'toc', + 'fenced_code', + 'tables', + 'attr_list', + 'footnotes', + 'def_list', + 'admonition' + ] + SUPPORTED_CONTENT = {'.md', '.markdown'} + IGNORED_DIRECTORIES = {'.git', '__pycache__', 'node_modules', '.github', 'venv', '.venv'} def __init__(self, input_dir: str, output_dir: str): self.input_dir = Path(input_dir) self.output_dir = Path(output_dir) self.markdown_converter = markdown.Markdown(extensions=self.MARKDOWN_EXTENSIONS) self.pages: Dict[Path, Page] = {} + self.categories: Dict[str, List[Page]] = defaultdict(list) + self.tags: Dict[str, List[Page]] = defaultdict(list) def generate_site(self) -> None: """Main method to generate the static site""" try: self._prepare_output_directory() self._process_content() + self._organize_content() self._copy_assets() + self._generate_special_pages() self._generate_html_pages() logger.info(f"Site generated successfully in {self.output_dir}") except Exception as e: @@ -49,9 +68,13 @@ def _prepare_output_directory(self) -> None: if self.output_dir.exists(): shutil.rmtree(self.output_dir) self.output_dir.mkdir(parents=True) - # Set directory permissions to 755 (rwxr-xr-x) self.output_dir.chmod(0o755) + # Create assets directory + assets_dir = self.output_dir / 'assets' + assets_dir.mkdir(parents=True) + assets_dir.chmod(0o755) + def _process_content(self) -> None: """Process all content in the input directory""" for file_path in self._walk_directory(self.input_dir): @@ -67,32 +90,76 @@ def _walk_directory(self, directory: Path) -> List[Path]: files.append(item) return files + def _extract_metadata(self, file_path: Path) -> dict: + """Extract metadata from markdown file""" + content = file_path.read_text(encoding='utf-8') + self.markdown_converter.reset() + self.markdown_converter.convert(content) + + metadata = {} + if hasattr(self.markdown_converter, 'Meta'): + metadata = { + 'title': self.markdown_converter.Meta.get('title', [file_path.stem.replace('-', ' ').title()])[0], + 'category': self.markdown_converter.Meta.get('category', [None])[0], + 'tags': self.markdown_converter.Meta.get('tags', [''])[0].split(',') if 'tags' in self.markdown_converter.Meta else [], + 'description': self.markdown_converter.Meta.get('description', [None])[0] + } + else: + metadata = { + 'title': file_path.stem.replace('-', ' ').title(), + 'category': None, + 'tags': [], + 'description': None + } + + return metadata + def _process_markdown(self, file_path: Path) -> None: """Process a markdown file into a Page object""" try: content = file_path.read_text(encoding='utf-8') + metadata = self._extract_metadata(file_path) + + # Convert content after metadata extraction self.markdown_converter.reset() html_content = self.markdown_converter.convert(content) - # Get title from metadata or filename - if hasattr(self.markdown_converter, 'Meta') and 'title' in self.markdown_converter.Meta: - title = self.markdown_converter.Meta['title'][0] - else: - title = file_path.stem.replace('-', ' ').title() - relative_path = file_path.relative_to(self.input_dir) is_index = file_path.stem.lower() == 'index' - self.pages[relative_path] = Page( - title=title, + # Clean and normalize tags + tags = [tag.strip().lower() for tag in metadata['tags'] if tag.strip()] + + page = Page( + title=metadata['title'], path=relative_path, content=html_content, modified_date=datetime.fromtimestamp(file_path.stat().st_mtime), + category=metadata['category'], + tags=tags, + description=metadata['description'], is_index=is_index ) + + self.pages[relative_path] = page + + # Organize by category and tags + if page.category: + self.categories[page.category].append(page) + for tag in page.tags: + self.tags[tag].append(page) + except Exception as e: logger.error(f"Failed to process {file_path}: {str(e)}") + def _organize_content(self) -> None: + """Organize pages by category and tags""" + # Sort pages within categories and tags + for category in self.categories: + self.categories[category].sort(key=lambda p: p.title) + for tag in self.tags: + self.tags[tag].sort(key=lambda p: p.title) + def _copy_assets(self) -> None: """Copy non-markdown files to output directory""" for file_path in self._walk_directory(self.input_dir): @@ -100,25 +167,147 @@ def _copy_assets(self) -> None: relative_path = file_path.relative_to(self.input_dir) output_path = self.output_dir / relative_path output_path.parent.mkdir(parents=True, exist_ok=True) - # Set directory permissions to 755 (rwxr-xr-x) output_path.parent.chmod(0o755) shutil.copy2(file_path, output_path) - # Set file permissions to 644 (rw-r--r--) output_path.chmod(0o644) + def _generate_special_pages(self) -> None: + """Generate special pages like category index and tag index""" + # Generate categories index + if self.categories: + categories_content = self._render_categories_index() + categories_page = Page( + title="Categories", + path=Path("categories/index.md"), + content=categories_content, + modified_date=datetime.now(), + category=None, + tags=[], + description="Index of all categories", + is_index=True + ) + self.pages[categories_page.path] = categories_page + + # Generate tags index + if self.tags: + tags_content = self._render_tags_index() + tags_page = Page( + title="Tags", + path=Path("tags/index.md"), + content=tags_content, + modified_date=datetime.now(), + category=None, + tags=[], + description="Index of all tags", + is_index=True + ) + self.pages[tags_page.path] = tags_page + + def _render_categories_index(self) -> str: + """Render the categories index page""" + content = "

    Categories

    \n" + return content + + def _render_tags_index(self) -> str: + """Render the tags index page""" + content = "

    Tags

    \n" + return content + def _generate_html_pages(self) -> None: """Generate HTML pages for all processed content""" + # Generate regular pages for page in self.pages.values(): output_path = self.output_dir / page.path.with_suffix('.html') output_path.parent.mkdir(parents=True, exist_ok=True) - # Set directory permissions to 755 (rwxr-xr-x) output_path.parent.chmod(0o755) html_content = self._render_template(page) output_path.write_text(html_content, encoding='utf-8') - # Set file permissions to 644 (rw-r--r--) output_path.chmod(0o644) + # Generate category pages + for category, pages in self.categories.items(): + self._generate_category_page(category, pages) + + # Generate tag pages + for tag, pages in self.tags.items(): + self._generate_tag_page(tag, pages) + + def _generate_category_page(self, category: str, pages: List[Page]) -> None: + """Generate a page for a specific category""" + output_path = self.output_dir / 'categories' / f"{category.lower()}.html" + output_path.parent.mkdir(parents=True, exist_ok=True) + output_path.parent.chmod(0o755) + + content = f"

    Category: {category}

    \n" + + page = Page( + title=f"Category: {category}", + path=Path(f"categories/{category.lower()}.md"), + content=content, + modified_date=datetime.now(), + category=None, + tags=[], + description=f"Pages in category {category}", + is_index=False + ) + + html_content = self._render_template(page) + output_path.write_text(html_content, encoding='utf-8') + output_path.chmod(0o644) + + def _generate_tag_page(self, tag: str, pages: List[Page]) -> None: + """Generate a page for a specific tag""" + output_path = self.output_dir / 'tags' / f"{tag.lower()}.html" + output_path.parent.mkdir(parents=True, exist_ok=True) + output_path.parent.chmod(0o755) + + content = f"

    Tag: {tag}

    \n" + + page = Page( + title=f"Tag: {tag}", + path=Path(f"tags/{tag.lower()}.md"), + content=content, + modified_date=datetime.now(), + category=None, + tags=[], + description=f"Pages tagged with {tag}", + is_index=False + ) + + html_content = self._render_template(page) + output_path.write_text(html_content, encoding='utf-8') + output_path.chmod(0o644) + + def _generate_breadcrumbs(self, page: Page) -> str: + """Generate breadcrumb navigation""" + parts = [] + parts.append('Home') + + if page.category: + parts.append(f'{page.category}') + + if not page.is_index: + parts.append(page.title) + + return ' » '.join(parts) + def _generate_navigation(self, current_page: Page) -> str: """Generate navigation links""" nav_items = [] @@ -127,17 +316,28 @@ def _generate_navigation(self, current_page: Page) -> str: if not current_page.is_index: nav_items.append('Home') - # Add other pages - for page in sorted(self.pages.values(), key=lambda p: p.title): - if not page.is_index: - relative_url = f"/{page.path.with_suffix('.html')}" - nav_items.append(f'{page.title}') + # Add categories link + if self.categories: + nav_items.append('Categories') + + # Add tags link + if self.tags: + nav_items.append('Tags') return '\n'.join(nav_items) def _render_template(self, page: Page) -> str: """Render HTML template for a page""" navigation = self._generate_navigation(page) + breadcrumbs = self._generate_breadcrumbs(page) + + # Generate tags section if page has tags + tags_section = "" + if page.tags: + tags_section = "
    Tags: " + ", ".join( + f'{tag}' + for tag in sorted(page.tags) + ) + "
    " return f''' @@ -145,12 +345,14 @@ def _render_template(self, page: Page) -> str: {page.title} + {f'' if page.description else ''} @@ -235,13 +513,18 @@ def _render_template(self, page: Page) -> str: {navigation}
    +

    {page.title}

    - Last modified: {page.modified_date.strftime('%Y-%m-%d')} + Last modified: {page.modified_date.strftime('%Y-%m-%d')} + {f'Category: {page.category}' if page.category else ''}
    {page.content}
    + {tags_section}
    ''' @@ -253,8 +536,12 @@ def main(): parser = argparse.ArgumentParser(description='Generate a static site from markdown files') parser.add_argument('input_dir', help='Input directory containing content') parser.add_argument('output_dir', help='Output directory for generated site') + parser.add_argument('--verbose', '-v', action='store_true', help='Enable verbose logging') args = parser.parse_args() + if args.verbose: + logging.getLogger().setLevel(logging.DEBUG) + try: generator = SiteGenerator(args.input_dir, args.output_dir) generator.generate_site() diff --git a/site/scripts/simple.html b/site/scripts/simple.html index 135222d2e..50ba0d010 100644 --- a/site/scripts/simple.html +++ b/site/scripts/simple.html @@ -4,12 +4,14 @@ Simple +
    +

    Simple

    - Last modified: 2024-03-04 + Last modified: 2024-03-04 +

    L1 Title

    @@ -255,6 +190,7 @@

    L3 Title

    L4 Title

    L4 content

    +
    \ No newline at end of file diff --git a/site/signal-conditioning/lecture-notes/lecture-1.html b/site/signal-conditioning/lecture-notes/lecture-1.html index 87887b406..aa7ba6273 100644 --- a/site/signal-conditioning/lecture-notes/lecture-1.html +++ b/site/signal-conditioning/lecture-notes/lecture-1.html @@ -4,12 +4,14 @@ Lecture 1 +
    +

    Lecture 1

    - Last modified: 2024-01-04 + Last modified: 2024-01-04 +

    C-SWAP

    @@ -256,6 +191,7 @@

    Power

    How much time do you use between charges. Device dissipates heat (ROT 10 mW/cm^3 -> 2 deg C)

    3 key sources: sensing, computing, communication.

    +
    \ No newline at end of file diff --git a/site/signal-conditioning/lecture-notes/lecture-2.html b/site/signal-conditioning/lecture-notes/lecture-2.html index d97164f12..2cd5c31c1 100644 --- a/site/signal-conditioning/lecture-notes/lecture-2.html +++ b/site/signal-conditioning/lecture-notes/lecture-2.html @@ -4,12 +4,14 @@ Lecture 2 +
    +

    Lecture 2

    - Last modified: 2024-02-10 + Last modified: 2024-02-10 +

    Lecture 2

    @@ -316,6 +251,7 @@

    Problems

    1 kW/m^2 * 10 m^2 * .2 = 2 kW = 2 kJ/sec = 2000 J/sec

    360,000,000 / 2000 J/sec = 180,000 sec = 50 hours

    +
    \ No newline at end of file diff --git a/site/signal-conditioning/lecture-notes/lecture-3.html b/site/signal-conditioning/lecture-notes/lecture-3.html index 9291ee7e8..4ef51d248 100644 --- a/site/signal-conditioning/lecture-notes/lecture-3.html +++ b/site/signal-conditioning/lecture-notes/lecture-3.html @@ -4,12 +4,14 @@ Lecture 3 +
    +

    Lecture 3

    - Last modified: 2024-01-23 + Last modified: 2024-01-23 +

    Lecture 3

    @@ -273,6 +208,7 @@

    Parallel

    $$I_t = I_1 + I_2 + \ldots + I_n$$

    $$I_t = V_t/R_t = V_t/(1/(1/R_1 + 1/R_2 + \ldots + 1/R_n)) = V_t/(R_1 + R_2 + \ldots + R_n) = V_t/R_1 + V_t/R_2 + \ldots + V_t/R_n = I_1 + I_2 + \ldots + I_n$$

    +
    \ No newline at end of file diff --git a/site/signal-conditioning/lecture-notes/lecture-4.html b/site/signal-conditioning/lecture-notes/lecture-4.html index 19d91a886..c620d6410 100644 --- a/site/signal-conditioning/lecture-notes/lecture-4.html +++ b/site/signal-conditioning/lecture-notes/lecture-4.html @@ -4,12 +4,14 @@ Lecture 4 +
    +

    Lecture 4

    - Last modified: 2024-01-23 + Last modified: 2024-01-23 +

    Lecture 4

    @@ -296,6 +231,7 @@

    Circuit

    +
    \ No newline at end of file diff --git a/site/signal-conditioning/lecture-notes/lecture-5.html b/site/signal-conditioning/lecture-notes/lecture-5.html index e5f7ac0db..b5decb05f 100644 --- a/site/signal-conditioning/lecture-notes/lecture-5.html +++ b/site/signal-conditioning/lecture-notes/lecture-5.html @@ -4,12 +4,14 @@ Lecture 5 +
    +

    Lecture 5

    - Last modified: 2024-01-23 + Last modified: 2024-01-23 +

    Thevenin's Theorem

    @@ -263,6 +198,7 @@

    Algorithm

  • find $R_{no}$, the equiv shunt (parallel with source) resistance between A and B by replacing voltage sources with short circuits and current sources with open circuits.
  • +
    \ No newline at end of file diff --git a/site/signal-conditioning/lecture-notes/lecture-6.html b/site/signal-conditioning/lecture-notes/lecture-6.html index fc877ae15..d8576278c 100644 --- a/site/signal-conditioning/lecture-notes/lecture-6.html +++ b/site/signal-conditioning/lecture-notes/lecture-6.html @@ -4,12 +4,14 @@ Lecture 6 +
    +

    Lecture 6

    - Last modified: 2024-02-27 + Last modified: 2024-02-27 +

    Capacitors

    @@ -306,6 +241,7 @@

    Impedance

    Phasors

    Complex numbers that represent the amplitude and phase of a sinusoidal signal. Can be used to represent AC signals and greatly simplify analysis by

    +
    \ No newline at end of file diff --git a/site/teaching/modern-java/collections-and-records.html b/site/teaching/modern-java/collections-and-records.html index fa7223a81..22eb7beb8 100644 --- a/site/teaching/modern-java/collections-and-records.html +++ b/site/teaching/modern-java/collections-and-records.html @@ -4,12 +4,14 @@ Collections And Records +
    +

    Collections And Records

    - Last modified: 2024-12-08 + Last modified: 2024-12-08 +

    Creating Collections and Data Types in Modern Java

    @@ -372,6 +307,7 @@

    Using this in Practice

    }
    +
    \ No newline at end of file diff --git a/site/teaching/modern-java/lambdas-and-streams.html b/site/teaching/modern-java/lambdas-and-streams.html index a479643ed..f650b3ee3 100644 --- a/site/teaching/modern-java/lambdas-and-streams.html +++ b/site/teaching/modern-java/lambdas-and-streams.html @@ -4,12 +4,14 @@ Lambdas And Streams +
    +

    Lambdas And Streams

    - Last modified: 2024-12-08 + Last modified: 2024-12-08 +

    A Soft Introduction to Java Streams and Lambdas

    @@ -388,6 +323,7 @@

    Grouping

    .collect(Collectors.groupingBy(User::getRole));
    +
    \ No newline at end of file diff --git a/site/tmp/bench/spec.html b/site/tmp/bench/spec.html index 42dc4c664..eb038a00d 100644 --- a/site/tmp/bench/spec.html +++ b/site/tmp/bench/spec.html @@ -4,12 +4,14 @@ Spec +
    +

    Spec

    - Last modified: 2024-05-11 + Last modified: 2024-05-11 +

    SWECCathon Project Spec

    @@ -411,6 +346,7 @@

    Bench Options

    +
    \ No newline at end of file diff --git a/site/tmp/pairing-algorithm.html b/site/tmp/pairing-algorithm.html index 4e7c570e5..e8b8cec03 100644 --- a/site/tmp/pairing-algorithm.html +++ b/site/tmp/pairing-algorithm.html @@ -4,12 +4,14 @@ Pairing Algorithm +
    +

    Pairing Algorithm

    - Last modified: 2024-03-22 + Last modified: 2024-03-22 +

    Formalizing the Pairing Algorithm for the SWECC Mock Interview Program

    @@ -252,7 +187,7 @@

    - A valid pair must have at least two 1-hour time slots in common in their availability. The number of common time slots is factored into the score of the pair. - Each student responds to a form while signing up. The responses are vectorized, and pairings are made based on the similarity of the responses.

    Statement of the Problem

    -

    Let $T^{7 \times 24}i$ be a bit-matrix of 1-hour time slots in a week for student $i$. The value of $T{i,j,k}$ is 1 if student $i$ is available at time slot $(j,k)$, and 0 otherwise.

    +

    Let $T^{7 \times 24}i$ be a bit-matrix of 1-hour time slots in a week for student $i$. The value of $T$ is 1 if student $i$ is available at time slot $(j,k)$, and 0 otherwise.

    $$ T_i = \begin{bmatrix} t_{1,1} & t_{1,2} & t_{1,3}& \cdots & t_{1,24} \ @@ -349,6 +284,7 @@

    Statement of the Problem

    return pairs ```

    +
    \ No newline at end of file