mirror of https://mirror.osredm.com/root/redis.git
Merge f1f9f63725
into d86cf66101
This commit is contained in:
commit
caa9a8a51a
|
@ -24,7 +24,7 @@ CLANG := $(findstring clang,$(shell sh -c '$(CC) --version | head -1'))
|
|||
# Optimization flags. To override, the OPTIMIZATION variable can be passed, but
|
||||
# some automatic defaults are added to it. To specify optimization flags
|
||||
# explicitly without any defaults added, pass the OPT variable instead.
|
||||
OPTIMIZATION?=-O3
|
||||
OPTIMIZATION?=-O0 -g
|
||||
ifeq ($(OPTIMIZATION),-O3)
|
||||
ifeq (clang,$(CLANG))
|
||||
OPTIMIZATION+=-flto
|
||||
|
@ -375,7 +375,7 @@ endif
|
|||
|
||||
REDIS_SERVER_NAME=redis-server$(PROG_SUFFIX)
|
||||
REDIS_SENTINEL_NAME=redis-sentinel$(PROG_SUFFIX)
|
||||
REDIS_SERVER_OBJ=threads_mngr.o memory_prefetch.o adlist.o quicklist.o ae.o anet.o dict.o ebuckets.o eventnotifier.o iothread.o mstr.o kvstore.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 cluster_legacy.o cluster_slot_stats.o crc16.o endianconv.o slowlog.o eval.o bio.o rio.o rand.o memtest.o syscheck.o crcspeed.o crccombine.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 lolwut8.o acl.o tracking.o socket.o tls.o sha256.o timeout.o setcpuaffinity.o monotonic.o mt19937-64.o resp_parser.o call_reply.o script_lua.o script.o functions.o function_lua.o commands.o strl.o connection.o unix.o logreqres.o
|
||||
REDIS_SERVER_OBJ=threads_mngr.o memory_prefetch.o adlist.o quicklist.o ae.o anet.o dict.o ebuckets.o eventnotifier.o iothread.o mstr.o kvstore.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 cluster_legacy.o cluster_slot_stats.o crc16.o endianconv.o slowlog.o eval.o bio.o rio.o rand.o memtest.o syscheck.o crcspeed.o crccombine.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 lolwut7.o lolwut8.o acl.o tracking.o socket.o tls.o sha256.o timeout.o setcpuaffinity.o monotonic.o mt19937-64.o resp_parser.o call_reply.o script_lua.o script.o functions.o function_lua.o commands.o strl.o connection.o unix.o logreqres.o
|
||||
REDIS_CLI_NAME=redis-cli$(PROG_SUFFIX)
|
||||
REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o ae.o redisassert.o crcspeed.o crccombine.o crc64.o siphash.o crc16.o monotonic.o cli_common.o mt19937-64.o strl.o cli_commands.o
|
||||
REDIS_BENCHMARK_NAME=redis-benchmark$(PROG_SUFFIX)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
void lolwut5Command(client *c);
|
||||
void lolwut6Command(client *c);
|
||||
void lolwut7Command(client *c);
|
||||
void lolwut8Command(client *c);
|
||||
|
||||
/* The default target for LOLWUT if no matching version was found.
|
||||
|
@ -55,6 +56,9 @@ void lolwutCommand(client *c) {
|
|||
else if ((v[0] == '6' && v[1] == '.' && v[2] != '9') ||
|
||||
(v[0] == '5' && v[1] == '.' && v[2] == '9'))
|
||||
lolwut6Command(c);
|
||||
else if ((v[0] == '7' && v[1] == '.' && v[2] != '9') ||
|
||||
(v[0] == '6' && v[1] == '.' && v[2] == '9'))
|
||||
lolwut7Command(c);
|
||||
else if ((v[0] == '8' && v[1] == '.' && v[2] != '9') ||
|
||||
(v[0] == '7' && v[1] == '.' && v[2] == '9'))
|
||||
lolwut8Command(c);
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 2023-Present, Redis Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under your choice of (a) the Redis Source Available License 2.0
|
||||
* (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
|
||||
* GNU Affero General Public License v3 (AGPLv3).
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* This file implements the LOLWUT command for Redis 7.
|
||||
* It generates a fractal tree pattern using ASCII art.
|
||||
*/
|
||||
|
||||
#include "server.h"
|
||||
#include "lolwut.h"
|
||||
#include "rand.h"
|
||||
#include <math.h>
|
||||
|
||||
/* Draw a tree branch using line drawing */
|
||||
void drawBranch(lwCanvas *canvas, int x1, int y1, int x2, int y2, int color) {
|
||||
lwDrawLine(canvas, x1, y1, x2, y2, color);
|
||||
}
|
||||
|
||||
/* Recursive function to draw a fractal tree */
|
||||
void drawTree(lwCanvas *canvas, int x, int y, int length, double angle, int depth, int color) {
|
||||
if (depth == 0 || length < 2) return;
|
||||
|
||||
/* Calculate end point of current branch */
|
||||
int x2 = x + (int)(length * cos(angle));
|
||||
int y2 = y + (int)(length * sin(angle));
|
||||
|
||||
/* Draw the branch */
|
||||
drawBranch(canvas, x, y, x2, y2, color);
|
||||
|
||||
/* Draw child branches with different angles and reduced length */
|
||||
double angleLeft = angle - M_PI / 6; /* 30 degrees left */
|
||||
double angleRight = angle + M_PI / 6; /* 30 degrees right */
|
||||
int newLength = length * 0.7; /* Reduce length by 30% */
|
||||
|
||||
/* Recursively draw left and right branches */
|
||||
drawTree(canvas, x2, y2, newLength, angleLeft, depth - 1, color);
|
||||
drawTree(canvas, x2, y2, newLength, angleRight, depth - 1, color);
|
||||
}
|
||||
|
||||
/* Generate multiple trees to create a forest */
|
||||
void generateFractalForest(lwCanvas *canvas, int num_trees, int max_depth) {
|
||||
int tree_spacing = canvas->width / (num_trees + 1);
|
||||
|
||||
for (int i = 0; i < num_trees; i++) {
|
||||
int x = tree_spacing * (i + 1);
|
||||
int y = canvas->height - 1; /* Start from bottom */
|
||||
int initial_length = canvas->height / 4 + (redisLrand48() % (canvas->height / 6));
|
||||
double angle = -M_PI / 2; /* Point upward */
|
||||
int depth = max_depth - (redisLrand48() % 2); /* Slight variation in depth */
|
||||
|
||||
drawTree(canvas, x, y, initial_length, angle, depth, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Render the canvas to ASCII art using simple characters */
|
||||
static sds renderTreeCanvas(lwCanvas *canvas) {
|
||||
sds text = sdsempty();
|
||||
|
||||
for (int y = 0; y < canvas->height; y++) {
|
||||
for (int x = 0; x < canvas->width; x++) {
|
||||
int pixel = lwGetPixel(canvas, x, y);
|
||||
if (pixel) {
|
||||
text = sdscatlen(text, "*", 1);
|
||||
} else {
|
||||
text = sdscatlen(text, " ", 1);
|
||||
}
|
||||
}
|
||||
if (y != canvas->height - 1) {
|
||||
text = sdscatlen(text, "\n", 1);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/* The LOLWUT 7 command:
|
||||
*
|
||||
* LOLWUT [width] [height] [trees] [depth]
|
||||
*
|
||||
* By default the command uses 80 columns, 25 rows, 5 trees, depth 6
|
||||
*/
|
||||
void lolwut7Command(client *c) {
|
||||
long cols = 80;
|
||||
long rows = 25;
|
||||
long num_trees = 5;
|
||||
long max_depth = 6;
|
||||
|
||||
/* 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;
|
||||
|
||||
if (c->argc > 3 &&
|
||||
getLongFromObjectOrReply(c,c->argv[3],&num_trees,NULL) != C_OK)
|
||||
return;
|
||||
|
||||
if (c->argc > 4 &&
|
||||
getLongFromObjectOrReply(c,c->argv[4],&max_depth,NULL) != C_OK)
|
||||
return;
|
||||
|
||||
/* Limits to ensure reasonable performance */
|
||||
if (cols < 10) cols = 10;
|
||||
if (cols > 200) cols = 200;
|
||||
if (rows < 10) rows = 10;
|
||||
if (rows > 100) rows = 100;
|
||||
if (num_trees < 1) num_trees = 1;
|
||||
if (num_trees > 20) num_trees = 20;
|
||||
if (max_depth < 1) max_depth = 1;
|
||||
if (max_depth > 10) max_depth = 10;
|
||||
|
||||
/* Generate the fractal forest and reply. */
|
||||
lwCanvas *canvas = lwCreateCanvas(cols, rows, 0);
|
||||
generateFractalForest(canvas, num_trees, max_depth);
|
||||
sds rendered = renderTreeCanvas(canvas);
|
||||
rendered = sdscat(rendered,
|
||||
"\nFractal trees generated using recursive algorithms.\n"
|
||||
"Each tree grows with mathematical precision, branching at angles\n"
|
||||
"that follow the golden ratio found in nature.\n"
|
||||
"\"In every walk in nature, one receives far more than they seek.\" - John Muir\n"
|
||||
"Redis ver. ");
|
||||
rendered = sdscat(rendered, REDIS_VERSION);
|
||||
rendered = sdscatlen(rendered, "\n", 1);
|
||||
addReplyVerbatim(c, rendered, sdslen(rendered), "txt");
|
||||
sdsfree(rendered);
|
||||
lwFreeCanvas(canvas);
|
||||
}
|
Loading…
Reference in New Issue