0. Preface
Here, the implementation of the Redis underlying string is analyzed, but it is not clear that the implementation of the completion of a concept, that is, why the author should be such a design, only to see a little, need to read the Redis how to use it back to experience, there are shortcomings also hope to inform.
Documents involved: SDS.H/SDS.C
1. Data structure:
1 Char *SDS; 2 3 struct SDSHDR {4 int len; // number of bytes already used in BUF 5 int free; // number of unused bytes in buf 6 Char buf[]; // buffers 7 };
The type returned by the API provided here is the SDS type (string), so that a part of the C string function can be reused.
The SDSHDR structure is used to store the string length information, which guarantees binary data security, that is, not only the string can be stored, but also can be used for storing other binary data
2. API implementation:
Extract only a few APIs, the full comment of the file on Githud (username: jabnih)
A. Sdsnewlen
Create an SDS string, and several other creation APIs are based on this API.
Create a one-time allocation of its required space, that is, the BUF is not re-allocated, reducing the calls to malloc, etc., while also reducing the number of free times when released
1 //creates an SDS string with the initial content of the content pointed to by Init, buf space is Initlen size2SDS Sdsnewlen (Const void*init, size_t Initlen) {3 structSDSHDR *sh;4 5 //we need to be aware6 if(init) {7 //init is not empty, the requested space is not initialized with malloc8SH = zmalloc (sizeof(structSDSHDR) +initlen+1);9}Else {Ten //init is empty, using calloc, the requested space is initialized to 0 OneSH = zcalloc (sizeof(structSDSHDR) +initlen+1); A } - - if(sh = = NULL)returnNULL; the -Sh->len =Initlen; -Sh-> Free=0; - //if Init is null here, the content of the BUF is 0 + if(Initlen &&init) -memcpy (sh->buf, Init, initlen); + ASh->buf[initlen] =' /'; at - return(Char*) sh->buf; -}
B. sdsmakeroomfor
The memory allocation policy for this API is: when it is less than Sds_max_prealloc(that is, 1M), it is pre-allocated with more than one space, and when it is greater than this threshold, only sds_max_prealloc memory is pre-allocated at a time.
1 //ensure that the SDS string has sufficient remaining unused space (greater than or equal to Addlen)2 SDS Sdsmakeroomfor (SDS s, size_t Addlen) {3 structSdshdr *sh, *newsh;4size_t Free=Sdsavail (s);5 size_t len, Newlen;6 7 //its remaining space satisfies the Addlen size8 if( Free>= Addlen)returns;9 Ten //does not meet addlen size and needs to be reassigned OneLen =Sdslen (s); ASH = (void*) (S (sizeof(struct( Sdshdr) )); - //The size required to use the new space is the length of the current SDS plus Addlen -Newlen = (len+Addlen); the //if the new space size is smaller than the set threshold, allocate some space at twice times the growth rate - if(Newlen <Sds_max_prealloc) -Newlen *=2; - Else + //larger than the set threshold, only increases the PREALLOC pre-allocation size -Newlen + =Sds_max_prealloc; + //Reassign Space Anewsh = Zrealloc (SH,sizeof(structSDSHDR) +newlen+1); at if(newsh = = NULL)returnNULL; - -Newsh-> Free= Newlen-Len; - returnNewsh->buf; -}
C. sdsremovefreespace
1 //removal of unused space in SDS strings, typically used when memory is tight2 SDS Sdsremovefreespace (SDS s) {3 structSDSHDR *sh;4 5SH = (void*) (S (sizeof(struct( Sdshdr) ));6SH = zrealloc (sh,sizeof(structSDSHDR) +sh->len+1);7Sh-> Free=0;8 9 returnSh->buf;Ten}
d. sdsclear
1 //empties the SDS string, but does not free up space2 voidSdsclear (SDS s) {3 structSdshdr *sh = (void*) (S (sizeof(struct( Sdshdr) ));4 5Sh-> Free+ = Sh->Len;6Sh->len =0;7sh->buf[0] =' /';8}
3. Summary:
1. Binary Data security
2. Pre-allocated space, can be lazy release, when the memory is tight can also reduce the unnecessary memory
3. Use this API to enable dynamic memory expansion (i.e., no need to consider whether memory space is sufficient)
4. Boundary check
Redis Learning--sds String implementation