Go实现简单的K-V存储

使用Go实现简单的K-V存储,包括基本的增删改查功能。

本节代码将实现K-V存储的四个基本功能:

  • 添加新元素
  • 基于key删除已有的元素
  • 给定key查找对应value
  • 修改key对应的value

我们将这四个功能命名为ADD,DELETE,LOOKUP,CHANGE,完成这四个基本功能,你将会对K-V存储的实现有一个全面的了解。另外,当你输入STOP时整个程序就会停止,输入PRINT命令就会打印出当前K-V存储的所有内容。

本节的keyValue.go将分为5个代码段解释。

第一部分:

package mainimport ("bufio""fmt""os""strings"
)type myElement struct {Name stringSurName stringId string
}var DATA = make(map[string]myElement)
复制代码

我们使用原生的Go map来实现K-V存储,因为内置的数据结构往往执行效率更高。map变量被声明为全局变量,其k为string类型,v为myElement类型,myElement是自定义的结构体。

第二部分代码:

func ADD(k string,n myElement) bool {if k == "" {return false}if LOOKUP(k) == nil {DATA[k] = nreturn true}return false
}func DELETE(k string) bool {if LOOKUP(k) != nil {delete(DATA, k)return true}return false
}
复制代码

这部分代码实现了命令行ADD和DELETE,用户在执行ADD命令时,如果没有携带足够的参数,我们要保证该操作不会失败,意味着myElement中对应的字段为空字符串。然而如果你要添加的key已经存在了,就会报错(K-V存储不允许重复key出现)而不是修改对应的值。

第三部分代码:

func LOOKUP(k string) *myElement  {_, ok := DATA[k]if ok {n := DATA[k]return &n} else {return nil}
}func CHANGE(k string, n myElement) bool {DATA[k] = nreturn true
}func PRINT()  {for k, v := range DATA {fmt.Printf("key: %s value: %v",k,v)}
}
复制代码

该代码段实现了LOOKUP与CHANGE功能,如果你要修改的key不存储,程序会自动将其存储。

PRINT命令能够打印出目前所有K-V存储的内容。

第四部分代码:

func main() {scanner := bufio.NewScanner(os.Stdin)for scanner.Scan() {text := scanner.Text()text = strings.TrimSpace(text)tokens := strings.Fields(text)switch len(tokens) {case 0:continuecase 1:tokens = append(tokens,"")tokens = append(tokens,"")tokens = append(tokens,"")tokens = append(tokens,"")case 2:tokens = append(tokens,"")tokens = append(tokens,"")tokens = append(tokens,"")case 3:tokens = append(tokens,"")tokens = append(tokens,"")case 4:tokens = append(tokens,"")}
复制代码

该部分代码读取用户的输入。首先,for循环将保证程序一直等待用户的输入,接下来使用tokens切片保证至少有5个元素的输入,即使只有ADD命令需要5个参数。如果用户不想在使用ADD命令时出现空字符串值,就需要这样输入:ADD aKey Field1 Field2 Field3。

最后一部分代码:

switch tokens[0] {case "PRINT":PRINT()case "STOP":returncase "DELETE":if !DELETE(tokens[1]) {fmt.Println("Delete operations failed")}case "ADD":n := myElement{tokens[2],tokens[3],tokens[4]}if !ADD(tokens[1],n) {fmt.Println("Add operation failed")}case "LOOKUP":n := LOOKUP(tokens[1])if n != nil {fmt.Printf("%v\n",n)}case "CHANGE":n := myElement{tokens[2],tokens[3],tokens[4]}if !CHANGE(tokens[1],n) {fmt.Println("Update operation failed")}default:fmt.Println("Unknown command - please try again!")}}
}
复制代码

这部分代码处理用户的输入。switch的使用使得程序的逻辑设计看上去十分清晰,能够将程序员从冗余的if...else中拯救出来。

执行keyValue.go得到如下输出:

$ go run keyValue.go
UNKNOWN
Unknown command - please try again!ADD 123 1 2 3
ADD 234 2 3 4
ADD 234
Add operation failed
ADD 345
PRINT
key: 123 value: {1 2 3}key: 234 value: {2 3 4}key: 345 value: {  }
CHANGE 345 3 4 5
PRINT
key: 345 value: {3 4 5}key: 123 value: {1 2 3}key: 234 value: {2 3 4}
DELETE 345
PRINT
key: 123 value: {1 2 3}key: 234 value: {2 3 4}
ADD 567 -5 -6 -7
PRINT
key: 123 value: {1 2 3}key: 234 value: {2 3 4}key: 567 value: {-5 -6 -7}
CHANGE 567
PRINT
key: 567 value: {  }key: 123 value: {1 2 3}key: 234 value: {2 3 4}
STOP
复制代码

本文节选自Mastring_Go_ZH_CN

查看并运行文中代码

戳我完整阅读本书

戳我提出你的建议

Go实现简单的K-V存储相关推荐

  1. 基于持久内存的 单机上亿(128B)QPS -- 持久化 k/v 存储引擎

    文章目录 性能数据 设计背景 设计架构 Hash 索引结构 及 PMEM空间管理形态 基本API 及 实现 API 初始化流程 写流程 读流程 删除流程 PMEM Allocator设计 主要组件 空 ...

  2. 分布式K/V存储方案

    引用:http://www.oschina.net/p/cassandra Apache Cassandra是一套开源分布式Key-Value存储系统.它最初由Facebook开发,用于储存特别大的数 ...

  3. Apache Accumulo 1.9.3 发布,高性能 K/V 存储方案

    Apache Accumulo 1.9.3 发布了,Apache Accumulo 是一个可靠的.可伸缩的.高性能的排序分布式的 Key-Value 存储解决方案,基于单元访问控制以及可定制的服务器端 ...

  4. KVell 单机k/v引擎:用最少的CPU 来调度Nvme的极致性能

    文章目录 前言 KVell背景 业界引擎使用Nvme的问题 CPU 会是 LSM-kv 存储的瓶颈 CPU 也会是 Btree-kv 存储的瓶颈 KVell 设计亮点 及 总体架构实现 KVell 设 ...

  5. 存储引擎 K/V 分离下的index回写问题

    前言 近期在做on nvme hash引擎相关的事情,对于非全序的数据集的存储需求,相比于我们传统的LSM或者B-tree的数据结构来说 能够减少很多维护全序上的计算/存储资源.当然我们要保证hash ...

  6. 时间序列数据库概览——基于文件(RRD)、K/V数据库(influxDB)、关系型数据库...

    一般人们谈论时间序列数据库的时候指代的就是这一类存储.按照底层技术不同可以划分为三类. 直接基于文件的简单存储:RRD Tool,Graphite Whisper.这类工具附属于监控告警工具,底层没有 ...

  7. badger 一个高性能的LSM K/V store

    大家好,给大家介绍一下, 新晋的高性能的 K/V数据库: badger. 这是 dgraph.io开发的一款基于 log structured merge (LSM) tree 的 key-value ...

  8. c语言map函数k v都是int,Go语言sync.Map(在并发环境中使用的map)

    Go语言中的 map 在并发情况下,只读是线程安全的,同时读写是线程不安全的. 下面来看下并发情况下读写 map 时会出现的问题,代码如下: // 创建一个int到int的映射 m := make(m ...

  9. JAVA day20、21 双列集合Map<K,V>:HashMap,LinkedHashMap,TreeMap,Hashtable, ConcurrentHashMap;JDK1.9新特性

    一.Map<K,V> Java提供了专⻔的集合类⽤来存放这种这种⼀⼀对应的关系,叫做映射对象,即 java.util.Map 接⼝. 类型参数: K - 此映射所维护的键的类型 V - 映 ...

  10. 深度学习attention机制中的Q,K,V分别是从哪来的?

    提问:找了各种资料,也读了论文原文,都是详细介绍了怎么把Q,K,V通过什么样的运算得到输出结果,始终没有一个地方有解释Q,K,V是从哪来的?一个layer的输入不就是一个tensor吗,为什么会有Q, ...

最新文章

  1. 【SICP练习】84 练习2.56
  2. linux 中php以及nginx的重启命令
  3. 小程序分享到朋友圈功能_来啦!小程序支持分享朋友圈
  4. 如何从开始掌控会议?
  5. Windows平台下 找回已丢失的MySql root 用户密码
  6. 需求分析的图形工具(层次方框 warnier IPO)
  7. python中head_Python(Head First)学习笔记:二
  8. PostgreSQL 10.1 手册_部分 II. SQL 语言_第 11 章 索引_11.11. 只用索引的扫描
  9. 检测手机屏幕是否亮屏解锁
  10. 图像增强python_Python图像增强简介(第1部分)
  11. 数据库关系代数表达式
  12. 百度离线地图JS API V3.0
  13. APP测试的主要内容
  14. 绝地求生 服务器无响应,绝地求生卡在登陆页面怎么办
  15. 计算机打不开guest用户,老司机应对win10系统打不开guest账户的恢复步骤
  16. pdf表格怎么转换成excel呢?
  17. (转)春节后面试别人的经历总结之二,好岗位分享给还在找工作中的软件开发爱好者们(适合初级者看)...
  18. 如何联系CSDN客服
  19. 网站安全有哪些防护措施?
  20. ***常用工具下载大全

热门文章

  1. Java学习笔记21
  2. Spark读取Parquet格式的数据为Dataframe
  3. LeetCode 3 无重复字符的最长子串
  4. Android OkHttp之 offline cache
  5. (0034) iOS 开发之UIView动画(过渡效果)
  6. PHP绕过disable_function限制(一)
  7. Java用Xom生成XML文档
  8. 省选专练(学习)可持久化Trie树(BZOJ3261)
  9. TouchDesigner 编译FlexChop
  10. apache环境下配置服务器支持https