A quick look at the Redis source code
heychinaski.com
heychinaski.com
http://web.archive.org/web/20180303001631/http://www.heychin...
I'm curious, which public codebases would you consider to be examples of well written Python?
Also, one thing that made a negative impression on me is https://github.com/antirez/redis/blob/unstable/src/adlist.c:
/* Free the whole list.
*
* This function can't fail. */
void listRelease(list *list)
{
unsigned long len;
listNode *current, *next;
current = list->head;
...
If you write such a comment, you better make sure it is true. And no, an early "list == NULL" check is not the only thing missing.Others mentioned kernel, GNOME. Redis is nice because it is fairly self contained. It has a good set of networking code, some command parsing, storage. Kind of a happy medium.
Anyway, I didn't look in depth at understanding the semantics of every module.
Here are some more things (besides NULL check I can see that are worrisome in that particular piece of code):
* can len be out of sync with actual list length
* can list->free be defined (non null) but value wasn't allocated with an malloc perhaps
* what if an element is inserted twice in list, will list->free be called on already free-ed area
* on 64 bit machine unsigned long will be 64 bit and on 32 bit it will be 32 bit, is that problem?
Which ones do you see?
Now those are issues I see by looking at the module in isolation. But it is not quite an isolated. It is part of a large module. Sometimes there are invariants that are enforced at the input (at the system boundary) and so it is not necessary to always keep checking for NULL or validating inputs in every single internal function.
That is one good lesson I learned from Erlang. Check your inputs at the boundary then code for the "happy" path and let error result in quick and early failure. Maybe prefer a quick segfault rather than a dangling pointer or wondering later how exactly to handle NULL pointer if it is not really expected to be NULL.
I've got a couple of general articles on adding a command and adding a datatype to Redis at http://starkiller.net, but I don't get too into existing code. I'd be interested in writing a bit more about the other data structures as well as the multiple strategies used for EXPIRE (which recently changed I believe).
http://pauladamsmith.com/articles/redis-under-the-hood.html
http://blog.togo.io/how-to/adding-interval-sets-to-redis
They have both been discussed before though.
{"get",getCommand,2,"r",0,NULL,1,1,1,0,0},
"The fourth field, set to "r", is specifying that the
command is read only and doesn’t modify any keys’ value
or state. There are a whole bunch of one letter flags
that you can specify in this string that are explained
in detail in the nearby block comment. The field
following this string should always be set to zero, and
will be computed later. It’s simply a bitmask
representation of the information implied by the string."
Why would you opt for this, when you could specify some constants and bitwise or them together? Isn't that a more common thing to do, than to calculate a bitwise flags at run time? COMMAND_READONLY | COMMAND_RANDOM | COMMAND_NOSIDEEFFECTS
ect ect ect.I'm sure there's a good reason, but this style seems strange to me.
Maybe redis makes use of the string later? but I can't help but feel it should build the string based on the flags, rather than build the flags based on the string.
ACTUALLY! It reminds me of a technique Bisqwit used when he made his emulator. He used strings to define the behavior of certain instructions, the strings were actually interpreted at compile time. Though I think this is a C++ specific trick.
http://www.youtube.com/watch?v=y71lli8MS8s
he brings in the instruction table at 1:30
Congratulations on the exploring.
I would also post link to my project, which is sort of 'Redis in Java', but it would be probably spam.