V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  roy2220  ›  全部回复第 2 页 / 共 3 页
回复总数  41
1  2  3  
2020-03-05 17:40:14 +08:00
回复了 roy2220 创建的主题 分享创造 用 go 实现一个简单的 KV 存储
@firemiles dei,自己实现的一个(比较 naive 的)存储层。详情看楼上,刚刚回复
2020-03-05 17:37:34 +08:00
回复了 roy2220 创建的主题 分享创造 用 go 实现一个简单的 KV 存储
@Comdex
@ClarkAbe 再说说文件空间管理的部分,为了把问题分而治之,我做一个“文件空间分配器”的抽象,只负责分配可用的文件空间(实际上就是一个文件偏移),充当最底层的存储层。分配算法上借鉴了现代内存分配器的思想,大块空间和小块空间分开治理,大块空间(>=64kb )使用了 buddy 分配算法(用位图做标记,用红黑树做空闲块索引)。小块内存用 freelist 管理(从 buddy 上分配一大块,挂到 freelist 上按需切割),还做了一些小块内存释放后和临近的小块合并的优化,用了侵入式循环双链表作为小块内存的 overhead,把所有空闲 or 非空闲的块串在一起,实现时间复杂度 O(1)的合并。但这些思路都是传统内存分配器上借鉴的,可能不太适用在文件空间的分配上,所以这个“文件空间分配器”还有很大的改进空间
2020-03-05 17:21:35 +08:00
回复了 roy2220 创建的主题 分享创造 用 go 实现一个简单的 KV 存储
@Comdex 哈哈,主要是我太懒了,感觉说话(表达)比写代码还要累。。。
实现细节还蛮多的,先说说哈希表的部分,普通的哈希表有一个致命的缺陷:当 numKeys/numBuckets 达到某个阀值( load factor )的时候,需要 rehash,这个操作会瞬间耗费大量的 cpu (而且哈希表构建在磁盘上的话,还要算上 io )。有没有办法把这个 rehash 的过程切分成一小步一小步,分摊到每次插入的操作上?这个就是<线性哈希>算法解决的问题。虽然 rehash 的过程被分摊了,但是 bucket 数组的空间还是需要连续的(不然没办法根据 hashcode 定位了),一般会采用“翻倍”的策略,让最大可用 bucket 的数量保持在 2^N。如果考虑存储海量的数据,bucket 数组空间翻倍(分配新的空间,拷贝旧数据到新空间,释放旧的空间)也是一个耗 cpu 和 io 的点。为了解决这个问题我把 bucket 数组切成固定长度的段( segment,64kb ),段与段之间不需要空间上的连续,然后额外维护一张段表(需要空间上连续)指向这些散落的段。这样就把 bucket 数组空间翻倍就弱化为段表空间翻倍,大大降低了影响。
2020-02-16 15:25:08 +08:00
回复了 roy2220 创建的主题 分享创造 在文件上实现 malloc 和 free
@Mithrandir 现在的方案是运行时用 mmap 地址+文件偏移定位数据块
2020-02-16 04:04:14 +08:00
回复了 roy2220 创建的主题 分享创造 在文件上实现 malloc 和 free
@codehz 实现上已经使用了 mmap 映射文件,但是每次内存映射的地址不确定(虽然 mmap 可以指定写死的映射地址,数据结构也就可以直接引用这个地址,因为不会变化,但是这样做太 trick ?)。还是记录文件偏移更健壮,外加使用 protobuf 做数据结构的序列化,这样大小端、内存对齐就和平台无关了
2020-02-06 10:36:24 +08:00
回复了 roy2220 创建的主题 分享创造 纯内存 B 树实现(使用 Go)
通过阅读源码的方式学习 Go 比较低效。建议先按官网的学习教程走,然后再看官方的 Effective Go。差不多了就可以挑一个项目进行练手了,练手过程中留意编码的最佳实践,可以多参考其他成熟的项目。后面根据自己遇到的问题,选读一些 Go 官方文档还有 Go Blog,github golang wiki 上也有不少有用的信息。大概就是一个循序渐进的过程,类似于“广度优先搜索”,不建议“深度优先搜索”的方式进行学习,例如一开始就细读所有官方文档,或者一头扎进代码堆
2018-07-16 13:38:29 +08:00
回复了 chai2010 创建的主题 Go 编程语言 pbgo: 基于 Protobuf 的 rpc/rest 迷你框架
哈哈,歪个楼,最近同撸了个基于 protobuf 的 rpc 轮子 github.com/let-z-go/pbrpc
2018-07-15 18:03:27 +08:00
回复了 coyove 创建的主题 Go 编程语言 potatolang 基于 go 的脚本语言
不错,我也撸过自己的玩具脚本语言: github.com/roy2220/oyc
2018-06-04 12:03:33 +08:00
回复了 zhang2e 创建的主题 分享发现 恭喜微软喜提 GitHub 👏
要迁移项目了
math.nan
2018-05-21 21:30:03 +08:00
回复了 songdg 创建的主题 Python 除了写循环还有什么更好的办法
我来偷个懒:
a = bytes([False, False, False, True, True, True, False, False, False, False, False, False])
b = bytes([True, True, True])
match = a.find(b) >= 0
print(match)
我选择 protobuf
2018-05-15 09:05:26 +08:00
回复了 roy2220 创建的主题 Python 用 asyncio 实现 zookeeper 客户端
@Lycnir 这个库之前用过,当时 bug 很多,行为也莫名其妙,现在看起来有所改善,但是对一些机制的实现还是错的
2018-05-10 13:01:16 +08:00
回复了 cheesea 创建的主题 Python Python 判断 str1 是否 str2 子串,为什么不用 KMP 算法呢?
因为这样做不对
@woscaizi 然而。。。并不是,其实我一开始我就不想回复你(因为觉得没有讨论的共识),但是又怕让你觉得我不太礼貌,只能硬着头皮回复(同时委婉表明我的态度),结果越来越尴尬。。。还是就此打住吧
@woscaizi 所以说这本身就是个很主观的问题。本主题的定位人群是认为 return 和 else 可读性不一致、想在两者寻找一个平衡的人,你大可无视本主题,它和你没什么关系
@woscaizi 光把逻辑写对还不够,可读性很重要,本主题的核心就是 return 与代码的可读性
@crb912 如果真的有一些简单武断的原则,只要竭力去遵守就能写出好代码,那满世界都是优秀程序员了,因为这太简单就能做到了。但现实并不是那么简单,动态地权衡和取舍才能做出好决定,不要盲目地相信各种原则(例如 DRY ?),它们通常都隐含着应用情景,无视应用情景妄想一招鲜,不是懒就是傻
@crb912 关于你的第二点,其实是我的描述不对,我所定义的"尽早返回"应该是直截了断,不应该留下 else 部分
@crb912 感谢讨论。每个人对代码可读性的理解不一样,其实这个问题没有的唯一正确的答案。上面所说的"正确"、"错误"并非指功能实现上,而且是风格上的。你指出的第 1 点主要是例子 1 的意外情况只有一个不太明显,如果例子 1 的意外情况很多,都用 if else 的写法,处理正常情况的逻辑会被嵌套得很深,不能一眼找出正常逻辑的部分
1  2  3  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   168 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 29ms · UTC 21:54 · PVG 05:54 · LAX 13:54 · JFK 16:54
Developed with CodeLauncher
♥ Do have faith in what you're doing.