• Sixteen corners

    Last year I built a library called Picnic for rendering data tables in monospaced environments like your terminal. Part of rendering the table is calculating what character to use for each wall and each corner separating the cells. Here’s a representative output with a bunch of different corner styles: │ compressed │ uncompressed ├───────────┬───────────┬───────┼───────────┬───────────┬──────── APK…

    Read More

  • Extracting 100% of Data From a Stubborn, Dying ZFS Pool

    In 2010 I built a home server with five 2TB drives. It ran Solaris and ZFS for the redundancy and data checksumming to ensure no data could be lost or corrupted. Just 16 months later five 3TB drives were added to the pool. This computer took the 2600-mile trip to live in San Francisco with…

    Read More

  • Removing Google as a Single Point of Failure

    I want to remove Google as a single point of failure in my life. They have two decades of my email. They have two decades of my photos. They have the only copy of thousands of documents, projects, and other random files from the last two decades. Now I trust Google completely in their ability…

    Read More

  • Removing Google as a Single Point of Failure Part 2: Gmail

    I want to remove Google as a single point of failure in my life. In the first blog post on this subject I detailed my setup for backing up Google Photos and Google Drive contents onto my home server and remotely to rsync.net. Left out of that post was a solution for Gmail because I…

    Read More

  • D8 Optimization: Assertions

    Note: This post is part of a series on D8 and R8, Android’s new dexer and optimizer, respectively. For an intro to D8 read “Android’s Java 8 support”. For an intro to R8 read “R8 Optimization: Staticization”. The assert keyword is quirky Java language syntax used for testing invariants. That is: things you expect to…

    Read More

  • Litmus-Testing Kotlin’s Many Memory Models

    When writing multiplatform code, Kotlin’s three compiler backends each have different memory models which must be considered. JavaScript is single-threaded so you really can do no wrong. The JVM model is arguably too permissive where you can do incorrect things and have them work 99.9% of the time. When targeting native, Kotlin enforces some invariants…

    Read More

  • Public API challenges in Kotlin

    Kotlin is justifiably lauded for its language features compared to today’s Java. It has constructs which allow expressing common patterns with more concise alternatives. An overused example in every intro-to-Kotlin talk or blog post is comparing a Java “POJO” to a Kotlin data class. Here’s yet another one of those comparisons, but bear with me…

    Read More

  • D8 Library Desugaring

    Note: This post is part of a series on D8 and R8, Android’s new dexer and optimizer, respectively. For an intro to D8 read “Android’s Java 8 support”. For an intro to R8 read “R8 Optimization: Staticization”. So far in this series the coverage of D8 has been about desugaring of Java 8 language features,…

    Read More

  • R8 Optimization: Enum Switch Maps

    Note: This post is part of a series on D8 and R8, Android’s new dexer and optimizer, respectively. For an intro to D8 read “Android’s Java 8 support”. For an intro to R8 read “R8 Optimization: Staticization”. The previous post on R8 covered enum ordinals which then allowed branch elimination to apply to a switch…

    Read More

  • D8 Optimizations

    Note: This post is part of a series on D8 and R8, Android’s new dexer and optimizer, respectively. For an intro to D8 read “Android’s Java 8 support”. For an intro to R8 read “R8 Optimization: Staticization”. No, that’s not a typo! While the optimizations in this series so far have been done by R8…

    Read More