traviscj/blog

Posts

May 31, 2018

constraint violations in tests

I had some test code that looked something like

@Test public void a() {
  db.insert(0, "a");
  assertThat(db.query(1).getKey()).isEqualTo("a");
}

@Test public void b() {
  db.insert(0, "a");
  db.insert(1, "b");
  assertThat(db.query(2).getKey()).isEqualTo("b");
}

@Test public void c() {
  assertThat(db.query(3)).isNull();
}

There’s some stuff to like about this:

  1. pretty straightforward which test is touching which records
  2. pretty clear what you expect to see in the database.

There’s a bunch of coincidences here that make this work, though:

read more
May 15, 2018

multiple thread test cases in java

Some of my day job lately has been trying to get a better handle on threads in Java. In particular, we had a really weird race condition resulting from multiple threads processing an input data stream and causing some unexpected conflicts in our data access layer.

To try to replicate the problem in tests, I started with something like this:

private static Runnable runWithDelay(String name, long millis) {
  return () -> {
    try {
      Thread.sleep(millis);
    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }
    System.out.println(name + " finished");
  };
}

This is just a Runnable that waits a while, and then prints that it finished. Then we can test with something like:

read more
April 25, 2018

big-ish personal storage

I was curious what it would cost to have something like 5-30TB of storage space on hand. The obvious choices are between buying some hard drives and paying for an S3 bucket or something.

The amazon costs are pretty straightforward: you pick a region, they tell you the cost. Starting with their pricing table:

aws = [
    {"level": "standard", "c_millidollars": 23},
    {"level": "infrequent", "c_millidollars": 12.5},
    {"level": "one_zone", "c_millidollars": 10},
    {"level": "glacier", "c_millidollars": 4}
]

we can say

read more
April 24, 2018

sfpark api

I recently came to learn of the SFpark API, which lets one make queries like:

LAT=37.787702
LONG=-122.407796
curl "http://api.sfpark.org/sfpark/rest/availabilityservice?lat=${LAT}&long=${LONG}&radius=0.25&uom=mile&response=json" | pbcopy
pbpaste | jq '.AVL[] | select (.TYPE | contains("OFF"))'

and get a response including records like:

{
  "TYPE": "OFF",
  "OSPID": "950",
  "NAME": "Union Square Garage",
  "DESC": "333 Post Street",
  "INTER": "Geary between Stockton & Powell",
  "TEL": "(415) 397-0631",
  "OPHRS": {
    "OPS": {
      "FROM": "7 Days/Wk",
      "BEG": "24 Hrs/Day"
    }
  },
  "OCC": "381",
  "OPER": "670",
  "PTS": "1",
  "LOC": "-122.407447946,37.7876789151"
}

Pretty cool!

read more
February 23, 2018

regex in java

I can never remember how to do java regexes with Pattern.

Pattern pattern = Pattern.compile("x_(yy|zz)");
String input = "x_yy";
boolean m = pattern.asPredicate().test(input);
System.out.println("matches: " + m);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
  System.out.println("whole matched string: " + matcher.group(0));
  System.out.println("matched group: " + matcher.group(1));
}

I also learned a really cool thing IntelliJ can do with pattern matches!

![java regex]({{ site.baseurl }}/assets/java-regex.png)

read more
January 26, 2018

guava RangeMap

We had some code like this:

NavigableMap<Double, Integer> PRIORITY_MULTIPLIERS = new TreeMap<Double, Integer>() {{ "{{ " }}
  put(LOW_THRESHOLD, 1);    // (20k..40k)  => 1
  put(MEDIUM_THRESHOLD, 2); // [40k..100k) => 2
  put(HIGH_THRESHOLD, 3);   // [100k..+∞)  => 3
}};

Integer getPriorityMultiplier(Double v) {
  if (v < LOW_THRESHOLD) {
    return 0;
  }
  return PRIORITY_MULTIPLIERS.floorEntry(v).getValue()
}

I replaced with a [RangeMap][RangeMap] that uses [Range][Range] instances as keys: [RangeMap]: https://google.github.io/guava/releases/16.0/api/docs/com/google/common/collect/RangeMap.html [Range]: https://google.github.io/guava/releases/16.0/api/docs/com/google/common/collect/Range.html

RangeMap<Double, Integer> PRIORITY_MULTIPLIERS = ImmutableRangeMap.<Double, Long>builder()
      .put(Range.lessThan(LOW_THRESHOLD), 0)
      .put(Range.closedOpen(LOW_THRESHOLD, MEDIUM_THRESHOLD), 1)
      .put(Range.closedOpen(MEDIUM_THRESHOLD, HIGH_THRESHOLD), 2)
      .put(Range.atLeast(HIGH_THRESHOLD), 3)
      .build();
Integer getPriorityMultiplier(Double v) {
  return rangePriorityMultipliers.get(v);
}

Advantages here being:

read more
January 12, 2018

osquery

I’ve known about [osquery][] for a while, but recently spent some time digging around in it. [osquery]: https://osquery.io The basic idea is to provide a consistent SQL interface to a bunch of system data, instead of learning idiosyncrasies of individual commands (which themselves vary across operating systems). My hacker buddy Sharvil has worked on osquery a fair bit and explained to me a couple years ago that it actually uses [sqlite][]’s [virtual table functionality][vtab] to provide the interface – it’s a fascinating and brilliant project! [sqlite]: https://sqlite.org/ [vtab]: https://sqlite.org/vtab.html

read more
January 9, 2018

profitably wrong

I’ve come to realize that my career so far has been built on being “profitably wrong.” I think this is interesting because the usual approaches are being “profitably fast” (optimizing) or “profitably better” (improving), and most people think of any kind of wrongness as being a terrible thing. But sometimes the best way to optimize or improve is approximating!

The definitions of “profitably” has changed as I’ve worked on different things, as has the specific type of “wrongness”. A couple specific ways accepting “wrongness” have been profitable for me include:

read more
January 5, 2018

todobackend.com

TodoBackend.com defines a simple API and has a frontend that works given any backend URL.

Particularly interesting to me:

  • haskell
    • super concise!
    • whoa, 6 different backends!
    • spock backend is crazy concise.
  • python + flask
    • seems like it would greatly benefit from a Store object
  • scala + akka
    • crazy pattern matching in routes definition
  • java + mangooio + jOOQ
    • especially the distinction between Todo and TodoPatch
    • also really glad I don’t have to write routes config separately from the code!
  • clojure + jetty/compojure + postgresql
  • rails
  • go + goa
read more
January 4, 2018

dancing bull pricing structure

Dancing Bull is a great Korean BBQ restaurant that opened nearby recently. They have this pricing scheme:

Note that the unlimited bulgogi is \$23/person, but the bulgogi a la carte is \$25/grill (with each additional orders after that costing \$9). This raises an obvious question: which is the better deal?

Spoiler: it depends on both how many people you have and how hungry they are.

First, we had to clarify how it actually worked. It’s not clear from the menu, but the “\$25/grill” includes the first order of bulgogi. Introducing $P$ for the number of people, $G$ for the number of grills, and $O$ for the total number of orders, we would pay $$UL = 23\cdot P$$ for the unlimited price scheme vs $$ALC = 25\cdot G + 9\cdot ( O - G)$$ for the a la carte scheme.

read more
  • ««
  • «
  • 2
  • 3
  • 4
  • 5
  • 6
  • »
  • »»
© traviscj/blog 2025