Skip to content

Instantly share code, notes, and snippets.

View aphyr's full-sized avatar
💭
be gay, do crimes

Kyle Kingsbury aphyr

💭
be gay, do crimes
View GitHub Profile
Let:
T1 = {:type :ok, :f :txn, :value [[:append 237 3] [:r 233 [1 3 5 6 7 8 9]] [:append 237 4] [:append 238 1]], :process 16, :time 207412818568, :index 4098}
T2 = {:type :ok, :f :txn, :value [[:append 233 10] [:r 239 [1]] [:append 237 5]], :process 22, :time 206702615066, :index 4054}
T3 = {:type :ok, :f :txn, :value [[:r 233 [1 3 5 6 7 8 9 10]] [:r 238 [2]] [:append 237 7] [:r 239 [1]]], :process 22, :time 206769955506, :index 4058}
T4 = {:type :ok, :f :txn, :value [[:append 238 3] [:append 237 8]], :process 22, :time 206852651070, :index 4060}
T5 = {:type :ok, :f :txn, :value [[:append 238 4] [:r 239 [1]] [:r 241 nil]], :process 22, :time 206919825209, :index 4064}
T6 = {:type :ok, :f :txn, :value [[:r 238 [2 3 4]] [:append 239 2] [:append 241 1] [:append 239 3]], :process 22, :time 206984932481, :index 4068}
T7 = {:type :ok, :f :txn, :value [[:r 241 [1 2 3]] [:r 239 [1 2 3]] [:append 238 6]], :process 22, :time 207330867948, :index 4090}
Then:
@aphyr
aphyr / gist:8e661dc2e45b35cd451f4831c524bb92
Created April 29, 2019 17:57
Cycle detection examples
Let:
T1 = {:type :ok, :f :txn, :value [[:append 1 4] [:r 0 nil]], :process 3, :time 8230766125, :index 17}
T2 = {:type :ok, :f :txn, :value [[:r 1 [2]] [:r 1 [2]] [:append 0 3]], :process 4, :time 8212723312, :index 15}
Then:
- T1 < T2, because T1 observed the initial (nil) state of 0, which T2 created by appending 3.
- However, T2 < T1, because T2 did not observe T1's append of 4 to 1: a contradiction!
Let:
(let [r0 {:type :ok, :f :read, :value {:x 0, :y 0} ; Initially, x and y are 0
i1 {:type :ok, :f :inc, :value [:x]} ; Increment key x by 1
r1 {:type :ok, :f :read, :value {:x 1, :y 0}} ; Read x and y
i2 {:type :ok, :f :inc, :value [:y] ; Increment y
r2 {:type :ok, :f :read, :value {:x 1, :y 1}} ; Read x and y
; So far, so good. The above set of txns is consistent with an order
; where i1 precedes i2. Now, let's have a read transaction which observed
; the *opposite* order of increments: i2 < i1.
r3 {:type :ok, :f :read, :value {:x 0, :y 1}}
@aphyr
aphyr / libfaketime.rb
Created February 25, 2019 21:21
libfaketime linux-brew recipe
class Libfaketime < Formula
desc "Report faked system time to programs"
homepage "https://github.com/wolfcw/libfaketime"
url "https://github.com/wolfcw/libfaketime/archive/v0.9.7.tar.gz"
sha256 "4d65f368b2d53ee2f93a25d5e9541ce27357f2b95e5e5afff210e0805042811e"
revision 1
head "https://github.com/wolfcw/libfaketime.git"
bottle do
rebuild 1
(defn real-pmap-with-early-abort
"Like real-pmap, but as soon as one thread throws an exception, all threads
are interrupted, and the original exception is rethrown. This is particularly
helpful when you want to do some all-or-nothing work, and the failure of any
piece means the entire results are invalid--or if the crash of one thread
could deadlock other threads."
[f coll]
(let [exception (promise)
thread-group (ThreadGroup. "real-pmap-with-early-abort")
results (vec (take n (repeatedly promise)))
; We use EDN as a serialization format in Clojure
user=> (require '[clojure.string :as str] '[clojure.edn :as edn])
nil
; Defrecords are a common way to represent data
user=> (defrecord Star [hair body face])
#<Class@28e8ba16 user.Star>
; Serializing a defrecord to EDN is easy
user=> (def s (pr-str (Star. "ga" "ga" "ooh la la")))
@aphyr
aphyr / video2gif.sh
Created March 28, 2018 04:07
Video to gif script
#!/bin/bash
# Args: input video file, start time in HH:MM:SS, duration in seconds, output
# gif file.
# Tmpdir
rm -rf /tmp/video2gif
mkdir /tmp/video2gif
mplayer -nosub -ao null -ss "$2" -endpos "$3" "$1" -vo jpeg:outdir=/tmp/video2gif:quality=100
@aphyr
aphyr / gist:0ad3458a1478db97517e7ac2faf2da00
Created October 5, 2017 19:13
Advice on benchmarking databases
Hi S-------. I'm not an expert in performance benchmarking--I focus on
correctness and safety--but I have a few pieces of advice here.
0. Pick multiple workloads that cover the gamut of behaviors in each DB.
*Don't* choose a completely sharded workload for VoltDB. Don't choose a
purely commutative workload for Cassandra. Cassandra's Paxos
implementation is slow and a good benchmark will demonstrate
that--however, it *doesn't* (I think?) require a global coordinator,
which means it might *scale* better than a single-coordinator system
like, say, VoltDB. Talk about those differences!
(def conf {:people [{:lang :clojure}, {:lang :ruby}, {:lang :m4}]})
(defn clojurists
"Returns all clojurists at a conference."
[conf]
(filter #(= :clojure (:lang %)) (:people conf)))
(defn final-person
"Returns the last attendee to the conference."
[conf]
(def example-history
{:txns [{:ops [{:f :read, :k :x, :v 1}]}]})
(defn index-txns
"Takes a raw history, and adds a sequential integer index :i to each txn in the history."
[raw-history]
(update example-history :txns
(partial map-indexed (fn [i txn] (assoc txn :i i)))))
; So in core.typed I'd type this as (ignoring type functions and just writing things out literally)