oh hai
commit
68e8d3528e
@ -0,0 +1,83 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
host = "localhost"
|
||||||
|
port = 6379
|
||||||
|
)
|
||||||
|
|
||||||
|
func usage(status int) {
|
||||||
|
fmt.Println("usage: rsload [filename]")
|
||||||
|
os.Exit(status)
|
||||||
|
}
|
||||||
|
|
||||||
|
func randomString(n int) string {
|
||||||
|
var alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
buf := make([]byte, n)
|
||||||
|
for i := 0; i < len(buf); i++ {
|
||||||
|
buf[i] = alpha[rand.Intn(len(alpha)-1)]
|
||||||
|
}
|
||||||
|
return string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
args := flag.Args()
|
||||||
|
if len(args) < 1 {
|
||||||
|
usage(1)
|
||||||
|
}
|
||||||
|
fname := args[0]
|
||||||
|
|
||||||
|
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", host, port))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("unable to connect to redis: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
f, err := os.Open(fname)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("unable to open file %s: %v\n", fname, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
c := make(chan statement)
|
||||||
|
go split(f, c)
|
||||||
|
|
||||||
|
s := randomString(32)
|
||||||
|
go func() {
|
||||||
|
for s := range c {
|
||||||
|
if err := s.write(conn); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(conn, "*2\r\n$4\r\necho\r\n$32\r\n%s\r\n", s)
|
||||||
|
}()
|
||||||
|
|
||||||
|
r := bufio.NewReader(conn)
|
||||||
|
for {
|
||||||
|
line, err := r.ReadString('\n')
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
if strings.TrimSpace(line) == s {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case io.EOF:
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,114 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type statement struct {
|
||||||
|
head *node
|
||||||
|
tail *node
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s statement) String() string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
s.each(func(n *node) error {
|
||||||
|
_, err := fmt.Fprint(&buf, n)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *statement) each(fn func(*node) error) error {
|
||||||
|
curr := s.head
|
||||||
|
for curr != nil {
|
||||||
|
err := fn(curr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
curr = curr.next
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *statement) write(w io.Writer) error {
|
||||||
|
return s.each(func(n *node) error {
|
||||||
|
_, err := w.Write(n.line)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type node struct {
|
||||||
|
line []byte
|
||||||
|
next *node
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n node) String() string {
|
||||||
|
return fmt.Sprintf("%s", n.line)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *statement) add(line []byte) {
|
||||||
|
n := &node{line, nil}
|
||||||
|
if s.head == nil {
|
||||||
|
s.head = n
|
||||||
|
} else if s.head.next == nil {
|
||||||
|
s.head.next = n
|
||||||
|
}
|
||||||
|
if s.tail != nil {
|
||||||
|
s.tail.next = n
|
||||||
|
}
|
||||||
|
s.tail = n
|
||||||
|
}
|
||||||
|
|
||||||
|
func whitespace(buf []byte) bool {
|
||||||
|
for i, _ := range buf {
|
||||||
|
switch buf[i] {
|
||||||
|
case '\r', '\n':
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func split(r io.Reader, c chan statement) {
|
||||||
|
defer close(c)
|
||||||
|
br := bufio.NewReader(r)
|
||||||
|
var s *statement
|
||||||
|
for {
|
||||||
|
line, err := br.ReadBytes('\n')
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
case io.EOF:
|
||||||
|
if s != nil {
|
||||||
|
c <- *s
|
||||||
|
}
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
fmt.Printf("error on read: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if whitespace(line) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if line[len(line)-2] != '\r' {
|
||||||
|
fmt.Printf("bad line terminator")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if line[0] == '*' {
|
||||||
|
if s != nil {
|
||||||
|
c <- *s
|
||||||
|
}
|
||||||
|
s = new(statement)
|
||||||
|
s.add(line)
|
||||||
|
} else {
|
||||||
|
if s == nil {
|
||||||
|
fmt.Println("ummm wut")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.add(line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue