Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
9073d56e
Commit
9073d56e
authored
Oct 04, 2019
by
antirez
Browse files
LOLWUT: refactoring + skeleton of LOLWUT 6.
parent
ee1cef18
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/Makefile
View file @
9073d56e
...
@@ -164,7 +164,7 @@ endif
...
@@ -164,7 +164,7 @@ endif
REDIS_SERVER_NAME
=
redis-server
REDIS_SERVER_NAME
=
redis-server
REDIS_SENTINEL_NAME
=
redis-sentinel
REDIS_SENTINEL_NAME
=
redis-sentinel
REDIS_SERVER_OBJ
=
adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o acl.o gopher.o tracking.o sha256.o
REDIS_SERVER_OBJ
=
adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o
lolwut6.o
acl.o gopher.o tracking.o sha256.o
REDIS_CLI_NAME
=
redis-cli
REDIS_CLI_NAME
=
redis-cli
REDIS_CLI_OBJ
=
anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o
REDIS_CLI_OBJ
=
anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o
REDIS_BENCHMARK_NAME
=
redis-benchmark
REDIS_BENCHMARK_NAME
=
redis-benchmark
...
...
src/lolwut.c
View file @
9073d56e
...
@@ -34,8 +34,11 @@
...
@@ -34,8 +34,11 @@
*/
*/
#include "server.h"
#include "server.h"
#include "lolwut.h"
#include <math.h>
void
lolwut5Command
(
client
*
c
);
void
lolwut5Command
(
client
*
c
);
void
lolwut6Command
(
client
*
c
);
/* The default target for LOLWUT if no matching version was found.
/* The default target for LOLWUT if no matching version was found.
* This is what unstable versions of Redis will display. */
* This is what unstable versions of Redis will display. */
...
@@ -47,11 +50,127 @@ void lolwutUnstableCommand(client *c) {
...
@@ -47,11 +50,127 @@ void lolwutUnstableCommand(client *c) {
sdsfree
(
rendered
);
sdsfree
(
rendered
);
}
}
/* LOLWUT [<version>] */
void
lolwutCommand
(
client
*
c
)
{
void
lolwutCommand
(
client
*
c
)
{
char
*
v
=
REDIS_VERSION
;
char
*
v
=
REDIS_VERSION
;
if
((
v
[
0
]
==
'5'
&&
v
[
1
]
==
'.'
)
||
char
verstr
[
64
];
if
(
c
->
argc
==
2
)
{
long
ver
;
if
(
getLongFromObjectOrReply
(
c
,
c
->
argv
[
1
],
&
ver
,
NULL
)
!=
C_OK
)
return
;
snprintf
(
verstr
,
sizeof
(
verstr
),
"%u.0.0"
,(
unsigned
int
)
ver
);
v
=
verstr
;
}
if
((
v
[
0
]
==
'5'
&&
v
[
1
]
==
'.'
&&
v
[
2
]
!=
'9'
)
||
(
v
[
0
]
==
'4'
&&
v
[
1
]
==
'.'
&&
v
[
2
]
==
'9'
))
(
v
[
0
]
==
'4'
&&
v
[
1
]
==
'.'
&&
v
[
2
]
==
'9'
))
lolwut5Command
(
c
);
lolwut5Command
(
c
);
else
if
((
v
[
0
]
==
'6'
&&
v
[
1
]
==
'.'
&&
v
[
2
]
!=
'9'
)
||
(
v
[
0
]
==
'5'
&&
v
[
1
]
==
'.'
&&
v
[
2
]
==
'9'
))
lolwut6Command
(
c
);
else
else
lolwutUnstableCommand
(
c
);
lolwutUnstableCommand
(
c
);
}
}
/* ========================== LOLWUT Canvase ===============================
* Many LOWUT versions will likely print some computer art to the screen.
* This is the case with LOLWUT 5 and LOLWUT 6, so here there is a generic
* canvas implementation that can be reused. */
/* Allocate and return a new canvas of the specified size. */
lwCanvas
*
lwCreateCanvas
(
int
width
,
int
height
)
{
lwCanvas
*
canvas
=
zmalloc
(
sizeof
(
*
canvas
));
canvas
->
width
=
width
;
canvas
->
height
=
height
;
canvas
->
pixels
=
zmalloc
(
width
*
height
);
memset
(
canvas
->
pixels
,
0
,
width
*
height
);
return
canvas
;
}
/* Free the canvas created by lwCreateCanvas(). */
void
lwFreeCanvas
(
lwCanvas
*
canvas
)
{
zfree
(
canvas
->
pixels
);
zfree
(
canvas
);
}
/* Set a pixel to the specified color. Color is 0 or 1, where zero means no
* dot will be displyed, and 1 means dot will be displayed.
* Coordinates are arranged so that left-top corner is 0,0. You can write
* out of the size of the canvas without issues. */
void
lwDrawPixel
(
lwCanvas
*
canvas
,
int
x
,
int
y
,
int
color
)
{
if
(
x
<
0
||
x
>=
canvas
->
width
||
y
<
0
||
y
>=
canvas
->
height
)
return
;
canvas
->
pixels
[
x
+
y
*
canvas
->
width
]
=
color
;
}
/* Return the value of the specified pixel on the canvas. */
int
lwGetPixel
(
lwCanvas
*
canvas
,
int
x
,
int
y
)
{
if
(
x
<
0
||
x
>=
canvas
->
width
||
y
<
0
||
y
>=
canvas
->
height
)
return
0
;
return
canvas
->
pixels
[
x
+
y
*
canvas
->
width
];
}
/* Draw a line from x1,y1 to x2,y2 using the Bresenham algorithm. */
void
lwDrawLine
(
lwCanvas
*
canvas
,
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
color
)
{
int
dx
=
abs
(
x2
-
x1
);
int
dy
=
abs
(
y2
-
y1
);
int
sx
=
(
x1
<
x2
)
?
1
:
-
1
;
int
sy
=
(
y1
<
y2
)
?
1
:
-
1
;
int
err
=
dx
-
dy
,
e2
;
while
(
1
)
{
lwDrawPixel
(
canvas
,
x1
,
y1
,
color
);
if
(
x1
==
x2
&&
y1
==
y2
)
break
;
e2
=
err
*
2
;
if
(
e2
>
-
dy
)
{
err
-=
dy
;
x1
+=
sx
;
}
if
(
e2
<
dx
)
{
err
+=
dx
;
y1
+=
sy
;
}
}
}
/* Draw a square centered at the specified x,y coordinates, with the specified
* rotation angle and size. In order to write a rotated square, we use the
* trivial fact that the parametric equation:
*
* x = sin(k)
* y = cos(k)
*
* Describes a circle for values going from 0 to 2*PI. So basically if we start
* at 45 degrees, that is k = PI/4, with the first point, and then we find
* the other three points incrementing K by PI/2 (90 degrees), we'll have the
* points of the square. In order to rotate the square, we just start with
* k = PI/4 + rotation_angle, and we are done.
*
* Of course the vanilla equations above will describe the square inside a
* circle of radius 1, so in order to draw larger squares we'll have to
* multiply the obtained coordinates, and then translate them. However this
* is much simpler than implementing the abstract concept of 2D shape and then
* performing the rotation/translation transformation, so for LOLWUT it's
* a good approach. */
void
lwDrawSquare
(
lwCanvas
*
canvas
,
int
x
,
int
y
,
float
size
,
float
angle
,
int
color
)
{
int
px
[
4
],
py
[
4
];
/* Adjust the desired size according to the fact that the square inscribed
* into a circle of radius 1 has the side of length SQRT(2). This way
* size becomes a simple multiplication factor we can use with our
* coordinates to magnify them. */
size
/=
1
.
4142135623
;
size
=
round
(
size
);
/* Compute the four points. */
float
k
=
M_PI
/
4
+
angle
;
for
(
int
j
=
0
;
j
<
4
;
j
++
)
{
px
[
j
]
=
round
(
sin
(
k
)
*
size
+
x
);
py
[
j
]
=
round
(
cos
(
k
)
*
size
+
y
);
k
+=
M_PI
/
2
;
}
/* Draw the square. */
for
(
int
j
=
0
;
j
<
4
;
j
++
)
lwDrawLine
(
canvas
,
px
[
j
],
py
[
j
],
px
[(
j
+
1
)
%
4
],
py
[(
j
+
1
)
%
4
],
color
);
}
src/lolwut.h
0 → 100644
View file @
9073d56e
/*
* Copyright (c) 2018-2019, Salvatore Sanfilippo <antirez at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* This structure represents our canvas. Drawing functions will take a pointer
* to a canvas to write to it. Later the canvas can be rendered to a string
* suitable to be printed on the screen, using unicode Braille characters. */
/* This represents a very simple generic canvas in order to draw stuff.
* It's up to each LOLWUT versions to translate what they draw to the
* screen, depending on the result to accomplish. */
typedef
struct
lwCanvas
{
int
width
;
int
height
;
char
*
pixels
;
}
lwCanvas
;
/* Drawing functions implemented inside lolwut.c. */
lwCanvas
*
lwCreateCanvas
(
int
width
,
int
height
);
void
lwFreeCanvas
(
lwCanvas
*
canvas
);
void
lwDrawPixel
(
lwCanvas
*
canvas
,
int
x
,
int
y
,
int
color
);
int
lwGetPixel
(
lwCanvas
*
canvas
,
int
x
,
int
y
);
void
lwDrawLine
(
lwCanvas
*
canvas
,
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
color
);
void
lwDrawSquare
(
lwCanvas
*
canvas
,
int
x
,
int
y
,
float
size
,
float
angle
,
int
color
);
src/lolwut5.c
View file @
9073d56e
...
@@ -34,17 +34,9 @@
...
@@ -34,17 +34,9 @@
*/
*/
#include "server.h"
#include "server.h"
#include "lolwut.h"
#include <math.h>
#include <math.h>
/* This structure represents our canvas. Drawing functions will take a pointer
* to a canvas to write to it. Later the canvas can be rendered to a string
* suitable to be printed on the screen, using unicode Braille characters. */
typedef
struct
lwCanvas
{
int
width
;
int
height
;
char
*
pixels
;
}
lwCanvas
;
/* Translate a group of 8 pixels (2x4 vertical rectangle) to the corresponding
/* Translate a group of 8 pixels (2x4 vertical rectangle) to the corresponding
* braille character. The byte should correspond to the pixels arranged as
* braille character. The byte should correspond to the pixels arranged as
* follows, where 0 is the least significant bit, and 7 the most significant
* follows, where 0 is the least significant bit, and 7 the most significant
...
@@ -69,104 +61,6 @@ void lwTranslatePixelsGroup(int byte, char *output) {
...
@@ -69,104 +61,6 @@ void lwTranslatePixelsGroup(int byte, char *output) {
output
[
2
]
=
0x80
|
(
code
&
0x3F
);
/* 10-xxxxxx */
output
[
2
]
=
0x80
|
(
code
&
0x3F
);
/* 10-xxxxxx */
}
}
/* Allocate and return a new canvas of the specified size. */
lwCanvas
*
lwCreateCanvas
(
int
width
,
int
height
)
{
lwCanvas
*
canvas
=
zmalloc
(
sizeof
(
*
canvas
));
canvas
->
width
=
width
;
canvas
->
height
=
height
;
canvas
->
pixels
=
zmalloc
(
width
*
height
);
memset
(
canvas
->
pixels
,
0
,
width
*
height
);
return
canvas
;
}
/* Free the canvas created by lwCreateCanvas(). */
void
lwFreeCanvas
(
lwCanvas
*
canvas
)
{
zfree
(
canvas
->
pixels
);
zfree
(
canvas
);
}
/* Set a pixel to the specified color. Color is 0 or 1, where zero means no
* dot will be displyed, and 1 means dot will be displayed.
* Coordinates are arranged so that left-top corner is 0,0. You can write
* out of the size of the canvas without issues. */
void
lwDrawPixel
(
lwCanvas
*
canvas
,
int
x
,
int
y
,
int
color
)
{
if
(
x
<
0
||
x
>=
canvas
->
width
||
y
<
0
||
y
>=
canvas
->
height
)
return
;
canvas
->
pixels
[
x
+
y
*
canvas
->
width
]
=
color
;
}
/* Return the value of the specified pixel on the canvas. */
int
lwGetPixel
(
lwCanvas
*
canvas
,
int
x
,
int
y
)
{
if
(
x
<
0
||
x
>=
canvas
->
width
||
y
<
0
||
y
>=
canvas
->
height
)
return
0
;
return
canvas
->
pixels
[
x
+
y
*
canvas
->
width
];
}
/* Draw a line from x1,y1 to x2,y2 using the Bresenham algorithm. */
void
lwDrawLine
(
lwCanvas
*
canvas
,
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
color
)
{
int
dx
=
abs
(
x2
-
x1
);
int
dy
=
abs
(
y2
-
y1
);
int
sx
=
(
x1
<
x2
)
?
1
:
-
1
;
int
sy
=
(
y1
<
y2
)
?
1
:
-
1
;
int
err
=
dx
-
dy
,
e2
;
while
(
1
)
{
lwDrawPixel
(
canvas
,
x1
,
y1
,
color
);
if
(
x1
==
x2
&&
y1
==
y2
)
break
;
e2
=
err
*
2
;
if
(
e2
>
-
dy
)
{
err
-=
dy
;
x1
+=
sx
;
}
if
(
e2
<
dx
)
{
err
+=
dx
;
y1
+=
sy
;
}
}
}
/* Draw a square centered at the specified x,y coordinates, with the specified
* rotation angle and size. In order to write a rotated square, we use the
* trivial fact that the parametric equation:
*
* x = sin(k)
* y = cos(k)
*
* Describes a circle for values going from 0 to 2*PI. So basically if we start
* at 45 degrees, that is k = PI/4, with the first point, and then we find
* the other three points incrementing K by PI/2 (90 degrees), we'll have the
* points of the square. In order to rotate the square, we just start with
* k = PI/4 + rotation_angle, and we are done.
*
* Of course the vanilla equations above will describe the square inside a
* circle of radius 1, so in order to draw larger squares we'll have to
* multiply the obtained coordinates, and then translate them. However this
* is much simpler than implementing the abstract concept of 2D shape and then
* performing the rotation/translation transformation, so for LOLWUT it's
* a good approach. */
void
lwDrawSquare
(
lwCanvas
*
canvas
,
int
x
,
int
y
,
float
size
,
float
angle
)
{
int
px
[
4
],
py
[
4
];
/* Adjust the desired size according to the fact that the square inscribed
* into a circle of radius 1 has the side of length SQRT(2). This way
* size becomes a simple multiplication factor we can use with our
* coordinates to magnify them. */
size
/=
1
.
4142135623
;
size
=
round
(
size
);
/* Compute the four points. */
float
k
=
M_PI
/
4
+
angle
;
for
(
int
j
=
0
;
j
<
4
;
j
++
)
{
px
[
j
]
=
round
(
sin
(
k
)
*
size
+
x
);
py
[
j
]
=
round
(
cos
(
k
)
*
size
+
y
);
k
+=
M_PI
/
2
;
}
/* Draw the square. */
for
(
int
j
=
0
;
j
<
4
;
j
++
)
lwDrawLine
(
canvas
,
px
[
j
],
py
[
j
],
px
[(
j
+
1
)
%
4
],
py
[(
j
+
1
)
%
4
],
1
);
}
/* Schotter, the output of LOLWUT of Redis 5, is a computer graphic art piece
/* Schotter, the output of LOLWUT of Redis 5, is a computer graphic art piece
* generated by Georg Nees in the 60s. It explores the relationship between
* generated by Georg Nees in the 60s. It explores the relationship between
* caos and order.
* caos and order.
...
@@ -200,7 +94,7 @@ lwCanvas *lwDrawSchotter(int console_cols, int squares_per_row, int squares_per_
...
@@ -200,7 +94,7 @@ lwCanvas *lwDrawSchotter(int console_cols, int squares_per_row, int squares_per_
sx
+=
r2
*
square_side
/
3
;
sx
+=
r2
*
square_side
/
3
;
sy
+=
r3
*
square_side
/
3
;
sy
+=
r3
*
square_side
/
3
;
}
}
lwDrawSquare
(
canvas
,
sx
,
sy
,
square_side
,
angle
);
lwDrawSquare
(
canvas
,
sx
,
sy
,
square_side
,
angle
,
1
);
}
}
}
}
...
...
src/lolwut6.c
0 → 100644
View file @
9073d56e
/*
* Copyright (c) 2019, Salvatore Sanfilippo <antirez at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------------
*
* This file implements the LOLWUT command. The command should do something
* fun and interesting, and should be replaced by a new implementation at
* each new version of Redis.
*/
#include "server.h"
#include "lolwut.h"
/* The LOLWUT 6 command:
*
* LOLWUT [columns] [rows]
*
* By default the command uses 80 columns, 40 squares per row
* per column.
*/
void
lolwut6Command
(
client
*
c
)
{
long
cols
=
80
;
long
rows
=
40
;
/* Parse the optional arguments if any. */
if
(
c
->
argc
>
1
&&
getLongFromObjectOrReply
(
c
,
c
->
argv
[
1
],
&
cols
,
NULL
)
!=
C_OK
)
return
;
if
(
c
->
argc
>
2
&&
getLongFromObjectOrReply
(
c
,
c
->
argv
[
2
],
&
rows
,
NULL
)
!=
C_OK
)
return
;
/* Limits. We want LOLWUT to be always reasonably fast and cheap to execute
* so we have maximum number of columns, rows, and output resulution. */
if
(
cols
<
1
)
cols
=
1
;
if
(
cols
>
1000
)
cols
=
1000
;
if
(
rows
<
1
)
rows
=
1
;
if
(
rows
>
1000
)
rows
=
1000
;
/* Generate the city skyline and reply. */
sds
rendered
=
sdsempty
();
rendered
=
sdscat
(
rendered
,
"
\n
Dedicated to the 8 bit game developers of the past. Redis ver. "
);
rendered
=
sdscat
(
rendered
,
REDIS_VERSION
);
rendered
=
sdscatlen
(
rendered
,
"
\n
"
,
1
);
addReplyVerbatim
(
c
,
rendered
,
sdslen
(
rendered
),
"txt"
);
sdsfree
(
rendered
);
// lwFreeCanvas(canvas);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment