Today began to study the Redis source code some of the tools in the implementation of the tool class in any language, the implementation of the algorithm principle should be the same, so you can take this opportunity to learn some of the more classical algorithms. Like I see today. CRC cyclic redundancy check algorithm and rand random number generation algorithm.
CRC algorithm full name cyclic redundancy check algorithm. The basic idea of CRC verification is to use the linear coding theory, at the transmitter end according to the K-bit binary sequence to be transmitted, to a certain rule to produce a verification of the supervisory code (both CRC code) R bit, and attached to the information behind, constitute a new binary sequence number of total (k+r) bit, and finally sent out. At the receiving end, the test is based on the rules followed between the information code and the CRC code to determine if there is an error in the transfer. The 16-bit CRC code produces the rule that the number of binary sequences to be sent is left 16 digits (multiplied), then divided by a polynomial, the final remainder is CRC code. The redundancy checking algorithm implemented in Redis is a byte-type algorithm.
The general description of the byte-type algorithm is: The CRC code of this byte, equal to the lower 8-bit left 8-bit of the last byte CRC code, and the last byte CRC is shifted to the right 8-bit to the CRC code that is different from or after the same byte.
The byte-type algorithm is as follows:
1 The CRC Register Group is initialized to all "0" (0x0000). (Note: CRC Register group initialization is all 1 o'clock, the final CRC should be reversed.) )
2 The CRC Register Group is shifted to the left 8 bits and is saved to the CRC Register Group.
3 The original CRC register group high 8 bits (8-bit right) and the data byte of the difference or operation, to get a point to the Value table index.
4 The index refers to the table value and CRC register group to do different or operations.
5 The data pointer plus 1, repeat step 2 if the data is not fully processed.
6) to obtain CRC.
We will correspond to the code in the Redis, fully compliant;
/* CRC64 cyclic redundancy algorithm, CRC: Base value 0,s: Incoming content, L: Content length * *
uint64_t CRC64 (uint64_t CRC, Const unsigned char *s, uint64_t l) {
UI nt64_t J;
for (j = 0; J < l; j +) {
uint8_t byte = s[j];
CRC = Crc64_tab[(uint8_t) CRC ^ Byte] ^ (CRC >> 8);
}
return CRC;
}
Redis Built in example,
*
the code for test main////
//* #ifdef test_main
#include <stdio.h>
int main (void) {
printf (" E9c6d914c4b8d9ca = =%016llx\n ",
(unsigned long Long) CRC64 (0, (unsigned char*)" 123456789 ", 9));
return 0;
}
Perform redundant operations on strings 1 through 9.
The following is the principle of the implementation of the stochastic algorithm in Redis, which initially assumed to be called the math. Rand () method, and later discovered that I was really wrong. The reasons given by the authors are:
/* Pseudo random number generation functions derived from the DRAND48 ()
* function obtained from Pysam source Code.
*
* This functions are used into-replace the default math.random ()
* Lua implementation with something ha Ving Tsun exactly the same behavior
* across different systems (by default Lua uses libc ' s rand ()-is not
* require D to implement a specific PRNG generating the same sequence
* in different (if systems) with the seeded integer. Same 7/>*
* The original code appears to is under the public domain.
* I modified it removing the non needed functions and all the 1960-style
coding C stuff ...
*
* Random functions may behave differently in different systems, and the authors do not use the math.random of the system itself,
but based on the drand48 () stochastic algorithm, rewrite the random function behavior, When rewriting random code, the author takes out unwanted methods
*----------------------------------------------------------------------------
That is to say, the author rewrites the random algorithm. Based on the algorithm implementation is DRAND48 () algorithm. Because this algorithm uses a 48-digit number, so use this name. Srand48 and drand48 are UNIX library functions, the function of drand48 is to generate a uniform distribution of random numbers between [0,1], using linear same congruential and 48-bit integer operations to produce pseudo-random sequence functions, using the above algorithm to produce a 48-bit pseudo random integer, And then remove the high 32 bits of this integer as random numbers, the 32-bit pseudorandom number is then programmed into [0,1], and the drand48 () is initialized with a function srand48, which is initialized only for the high 32 bits of the 48-bit integer, and its lower 16 bits are set to random values. This is a kind of pseudo random generator with better statistic property. These 2 functions are implemented in the original C language:
#ifndef drand48_h
#define DRAND48_H
#include <stdlib.h>
#define m 0X100000000LL
#define C 0XB16
#define A 0x5deece66dll
static unsigned long long seed = 1;
Double drand48 (void)
{
seed = (A * seed + C) & 0xFFFFFFFFFFFFLL;
unsigned int x = seed >>;
Return (Double) x/(double) m);
void srand48 (unsigned int i)
{
seed = ((Long long int i) <<) | rand ();
}
#endif
Because the rand () function of the system is used here, the z author does not use the system itself, so the implementation here is slightly different in Redis:
int32_t redisLrand48 () {
next ();
Return (((int32_t) x[2] << (N-1)) + (X[1] >> 1));
/* Set seed */
void redisSrand48 (int32_t seedval) {
seed (X0, Low (Seedval), High (Seedval));
static void Next (void) {
uint32_t p[2], q[2], r[2], carry0, carry1;
MUL (A[0], x[0], p);
Addequ (P[0], C, carry0);
Addequ (P[1], carry0, carry1);
MUL (A[0], x[1], q);
Addequ (P[1], q[0], carry0);
MUL (A[1], x[0], R);
X[2] = Low (carry0 + Carry1 + CARRY (p[1), r[0]) + q[1] + r[1] +
a[0] * x[2] + a[1] * x[1] + a[2] * x[0);
X[1] = Low (p[1] + r[0]);
X[0] = Low (p[0]);
The implementation of the specific next, referring to the source code, various 4 operations and operations.