[MySQL 学习] zlib库相关结构和函数

以下主要是阅读zlib库时,对库函数的注释的翻译,也是为了帮助理解zlib在innodb压缩表中的应用

这里只考虑了Innodb用到的函数,其他的具体参考zlib.h文件,里面的注释写的非常详细

————————-

1.主要用到的结构体是z_stream,定义在文件zlib/zlib.h中,我们需要去定义的字段包括

Bytef    *next_in 输入的源字符串
uInt     avail_in 输入源字符串长度,当avail_in下降到0时,必须更新next_in和avail_in
Bytef    *next_out 输出字符串
uInt     avail_out 在next_out中的可用空闲空间,当avail_out下降到0时,必须更新next_out
alloc_func zalloc
内存分配函数,Innodb里对应的函数指针是page_zip_zalloc

如不指定需要设置为NULL

free_func  zfree 内存释放函数,Innodb里对应函数指针为page_zip_free
如不指定需要设置为NULL
voidpf     opaque 会被作为参数传递给zalloc和zfree,在innodb里使用的是mem_heap.

2.压缩函数(只涉及到Innodb中的调用)

a.deflateInit2(strm, level, method, windowBits, memLevel, strategy)

参数

@1, z_stream对象

@2,压缩级别

@3,值为Z_DEFLATED,当前唯一的defalte压缩方法,用于以后扩展

@4,窗口比特数,范围在8~15,更大的值意味着消耗更多的内存来获得更好的压缩效果,如果使用deflateInit来初始化的话默认值为15

windowBits也可以在-8~-15间赋值,用于raw deflate(不理解?),这时候使用-windowsBits来决定窗口大小,deflate()会生成raw deflate data,没有zlib头和尾,并且也不会去调用adler32

当使用gzlib编码时,windowsbits也可以设置为大于15,但跟zlib的文件格式会有很大的不同。

在Innodb中值为UNIV_PAGE_SIZE_SHIFT,值为14(如果Page Size为默认16K的话)

@5,memlevel用于指定分配多少内存用于内部的压缩状态,值为1将使用最小的内存但更慢并降低压缩比;memlevel值为9时,会使用最大内存来获得最快的速度。默认值为8,在Innodb里使用的值为MAX_MEM_LEVEL,deflate需要的内存为:

(1 << (windowBits+2)) +  (1 << (memLevel+9))

@6,用于调整压缩算法

包括以下值:

Z_DEFAULT_STRATEGY, 用于普通数据

Z_FILTERED,用于由filter(或者称为predictor)生成的数据.过滤的数据包含很多小的随机数据。这种情况下,压缩算法能够获得更好的压缩效果。该选项可以强制更多的哈夫曼编码和更少的字符匹配。有时候可以作为Z_DEFAULT_STRATEGY和Z_HUFFMAN_ONLY的折衷。

Z_HUFFMAN_ONLY,用于强制哈夫曼编码(不做字符匹配)

Z_RLE,限制匹配长度为1(run-length encoding),用于设计的和Z_HUFFMAN_ONLY一样快速,但对PNG图片类型会获得很好的压缩效果

Z_FIXED,阻止使用动态哈夫曼编码,从而允许获得更简单的解码

strategy参数只影响压缩比,而不会影响到压缩输出的正确性,因此没有正确的设置也不要紧。

b.deflate(strm, flush)

deflate尽可能的进行数据压缩,如果输入缓存变空或者输出缓冲变慢了才会停止。除了需要强制刷新,可能会引入一些延迟(读取输入数据,而不产生输出)

-从next_in开始压缩更多的数据,并更新相应的next_in和avail_in。如果无法处理所有的输入(因为在输出缓存中没有足够的空间),next_in和avail_in会在当前点更新并在下次调用delfate时从当前点重新开始。

-从next_out开始产生更多的输出,并更新相应的next_out和avail_out。当flush参数为非0值时,上述行为会被强制执行,强制频繁的刷新会降低压缩比,所以该参数应该只在需要的时候才去设置它(例如交互式应用)。即使没有设置flush,也需要提供一些输出。

在调用deflate函数之前,应用需要确定以上至少有一个行为是可行的(通过提供更多的输入或消费更多的输出,并更新相应的avail_in活avail_out)。在调用deflate前,avail_out不可为空。应用能够在需要时候消费压缩数据输出,例如,在输出缓冲满时(avail_out==0),或者每次调用deflate函数之后。如果deflate返回值为Z_OK并且avail_out值为0,在清空输出缓冲后,需要再次调用deflate,因为有可能还有更多未完成的数据。

通常情况下, flush参数被设置为Z_NO_FLUSH,这允许deflate来决定在产生输出前积攒多少数据,以获得更好的压缩效果。

当flush被设置为:

Z_SYNC_FLUSH,所有pending的输出被刷新到输出缓冲,以字节边界对齐,这样解压器能够获得当前所有可用的输入数据。(特别是如果有足够的输出缓冲,在调用函数后,avail_in值为0)。flush操作可能会降低压缩效果,所以应该只在需要使用。在完成当前delfate块后,随后是一个空的存储块,在下个字节里有3个bit的留白,随后是4个字节(00 00 FF FF)

Z_PARTIAL_FLUSH,所有pending的输出被刷新到输出缓冲,但不以一个字节边界对齐,当设置为该值时,所有当前的输入数据对解压器而言是可用的。这确保了足够的字节按序输出给解压器,以在空的固定代码块之前完成block

Z_BLOCK,如果一个deflate块结束并提交,但输出不做对其,并且当前块最多保留7个Bits,在下一次deflate块完成后作为next byte写入。这种情况下,解压器可能无法提供足够的bit去完成数据解压以提供给压缩器。这需要下一个block提交后才能完成。

Z_FULL_FLUSH,所有的输出都被刷新,所有的压缩状态也被重置。这样如果当前压缩数据损坏或者需要随机访问时,解压操作可以从这个点重新开始。太频繁的使用Z_FULL_FLUSH会验证的降低压缩性。

如果deflate返回并且avail_out值为0,该函数必须再次使用相同的flush参数调用,并预留足够的输出空间,直到flush完成(defalte返回非0的avail_out)。当使用Z_FULL_FLUSH或Z_SYNC_FLUSH时,确保avail_out大于6以避免重复的flush标记。

Z_FINISH,pending的输入被执行,pengding的输出被刷新,如果有足够的输出空间时,deflate返回值为Z_STREAM_END。如果deflate返回Z_OK,该函数必须再次调用一次。在返回Z_STREAM_END之后,唯一可以进行的操作就是deflateReset或者deflateEnd。 如果所有的压缩可以在单独一步完成时,Z_FINISH可以在defalteinit后立即使用。这种情况下,avail_out的值最少为deflateBound返回的值。这样deflate才能确保返回Z_STREAM_END。

deflate()会在strm->adler上设置当前所有输入的adler32 checksum值;另外也可能更新strm->data_type值(如果能够猜测输入数据的类型,Z_BINARY或者Z_TEXT)。

c. deflateEnd (strm)

所有动态分配的数据结构都被释放掉,并抛弃所有未完成的输入,也不会刷新任何pending的输出。

成功时返回Z_OK,失败时返回Z_STREAM_ERROR

d.inflateInit2(strm, windowBits)

用于初始化解压z_streamp

跟deflateInit2类似,在调用该函数之前,同样需要先初始化next_in, avail_in, zalloc, zfree 以及 opaque

注意解压时提供的windowBits不能比压缩时的windowBits大,否则在解压时inflate会返回错误Z_DATA_ERROR。

e.inflate(strm, flush)

inflate与deflate相反,根据strm尽可能的解压数据。

flush参数可以是Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,Z_BLOCK, 或者 Z_TREES。Z_SYNC_FLUSH要求infalte尽可能的刷新到输出缓冲。Z_BLOCK要求在获取下一个deflate 块的边界inflate需要停止。当解码zlib或gzip格式时,这会导致infalte在压缩数据头部和在第一个block之前会立刻返回。

Z_BLOCK选项有助于在append或组合defalte stream是。inflate在返回时会设置strm->data_type为从strm->next_in中最后一个字节中未使用的Bit数字。如果inflate正在解码最后一个block,值为64;如果在解码end-of-block code或者解码完整的头部

Z_TREES行为和Z_BLOCK类似,但它也会在每次到达一个deflate块头的尾部,在该块上任何实际需要解码的数据之前返回。这允许调用者决定deflate块头的长度,用于随后在一个deflate块中的随机访问。当到达deflate块头尾部时,inflate返回,并设置strm->data_type值为256.

infalte()应该被反复调用,直到其返回值为Z_STREAM_END或者返回一个错误。然而,如果所有的压缩操作可以单独一个步骤来完成(只调用一次inflate),flush应该被设置为Z_FINISH。这种情况下,所有pending的输入被处理,所有pending的输出被刷新;avail_out必须足够大,来存储解压数据。Z_FINISH也许不是必须的,但他可以用来告诉inflate去使用更快的方法来完成一次inflate调用。Z_FINISH也告诉inflate如果stream完成了,无需维护一个滑动窗口,这减少了inflate的内存占用。如果stream没有完成,或者由于没有提供全部的stream,或者没有提供足够的输出空间,就会分配一个滑动窗口,inflate可以被再次调用去完成操作(就像使用Z_NO_FLUSH那样)

f.inflateEnd(strm)

释放所有动态分配的内存

时间: 2024-10-15 02:27:47

[MySQL 学习] zlib库相关结构和函数的相关文章

Mysql学习笔记(四)字符串函数

原文:Mysql学习笔记(四)字符串函数 PS:终于看完了字符串函数,心都快碎了...涉及的函数真是太多了...感觉这里的字符串函数和JAVA里的基本都差不多了...基本上算是掌握了,但是想全记住那是不太可能的... 学习内容: 字符串函数的掌握和应用.. ASCii(str) 返回字符串的最左边的ascii码值..如果str为NULL,那么返回NULL...如果字符串为0,那么返回也为0...   mysql>select ascii('2'); mysql>select ascii('dx

Shell编程学习:Shell子程序结构和函数

函数可以简化代码,实现脚本代码重用.一次定义可以多次调用.结构化编程,增强可读性,可以将功能定义为多个函数,然后保存在一个文件中,然后在~/bashrc或者在命令行使用source(.)调用这个文件.加快运行速度 1.定义函数的方法(传统风格) function name{ } C语言风格: name(){ } 推荐使用C语言风格,兼容性好,可以在csh/tsch中使用 函数中return和exit的区别,return退出执行,返回到主程序函数之后继续执行 exit直接退出当前脚本. shell

PHP GD库相关图像生成和处理函数小结_php技巧

本文总结了PHP GD库相关图像生成和处理函数.分享给大家供大家参考,具体如下: 这几天在学习图像验证码部分,参考了许多例子,都是用GD库来生成和绘制图像的,所以打算把GD库封装成类来使用,顺便也学习和练习一下PHP面向对象部分. 首先分析一下GD库所提供的函数,依据功能作了划分:(这只是常用的基础级函数,更高级的函数稍后再作研究) 1. create // 图像生成 A.绘制图像 imageCreate // 基于调色板(256色)的图像(gif/*) imageCreateTrueColor

我的MYSQL学习心得(十) 自定义存储过程和函数

这一篇<我的MYSQL学习心得(十)>将会讲解MYSQL的存储过程和函数 MYSQL中创建存储过程和函数分别使用CREATE PROCEDURE和CREATE FUNCTION 使用CALL语句来调用存储过程,存储过程也可以调用其他存储过程 函数可以从语句外调用,能返回标量值 创建存储过程 语法 CREATE PROCEDURE sp_name ([ proc_parameter ]) [ characteristics..] routine_body  proc_parameter指定存储过

我的MYSQL学习心得(六) 函数

这一节主要介绍MYSQL里的函数,MYSQL里的函数很多,我这里主要介绍MYSQL里有而SQLSERVER没有的函数 数学函数 1.求余函数MOD(X,Y) MOD(X,Y)返回x被y除后的余数,MOD()对于带有小数部分的数值也起作用,他返回除法运算后的精确余数 SELECT MOD(31,8)   2.四舍五入函数TRUNCATE(X,Y) TRUNCATE(X,Y)返回被舍去至小数点后y位的数字x.若y的值为0,则结果不带有小数点或不带有小数部分. 若y设为负数,则截去(归零)x小数点左边

slq server、oracle、mysql学习相关资料

问题描述 slq server.oracle.mysql学习相关资料 想学习数据库,有没有推荐slq server.oracle.mysql学习相关资料.书籍.网站 解决方案 51ctoverycd脚本之家verydemo这些网站有视频和资料,你可以自己进去找的: 如果回答对您有帮助请采纳 解决方案二: http://wenku.baidu.com/view/f3ac9d0b79563c1ec5da711d.html

mysql-数据库学习的一些相关问题

问题描述 数据库学习的一些相关问题 程序员小菜鸟,想要学习数据库,现在的水平仅限于会一些基本的sql语句,然后想买书学习, 去查了查推荐的书籍,发现很多推荐〈Microsoft SQL Server 2005技术内幕〉系列丛书 以及<SQL Server 2005开发.管理与应用实例>,然后想问一下,这些书中讲的内容 仅限于sql server数据库还是说基本都能用 另外看看有没有可以推荐的书籍,现在应该学原理的还是直接学sql语句比较合适 解决方案 如果是没有一点数据库理论基础的话,建议还是

Mysql学习笔记(十)存储过程与函数 + 知识点补充(having与where的区别)

原文:Mysql学习笔记(十)存储过程与函数 + 知识点补充(having与where的区别) 学习内容:存储程序与函数...这一章学的我是云里雾里的... 1.存储过程...   Mysql存储过程是从mysql 5.0开始增加的一个新功能.存储过程的优点其实有很多,不过我觉得存储过程最重要的优点就是实现了SQL代码的封装,那么我们为什么需要封装SQL语句呢?原因就是当我们在面对一个庞大的数据库的时候,当我们使用外部程序去访问数据库的时候...我们总不能在外部程序中内嵌很多的SQL语句吧...

Mysql学习笔记(五)数学与日期时间函数

原文:Mysql学习笔记(五)数学与日期时间函数 学习内容: 1.数学函数 2.日期时间函数 这些函数都是很常用的函数...在这里进行简单的介绍... 数学函数: mysql> SELECT ABS(-32); //取绝对值函数 -> 32 这个函数可安全地使用于 BIGINT 值. mysql> SELECT SIGN(-32);//判断一个数是正数,负数,还是0..根据实际情况返回指定的数值.. -> -1 mysql> SELECT MOD(234, 10);//取模函