gin 框架原理

2023-05-16

Gin的路由原理

Gin的路由基于Trie树和压缩字典树算法,什么是Trie树?其实很好理解,看下图:

单词at,bee,ben,bt,q组成的Trie树如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6eit5hrb-1650874176285)(https://www.hengyumo.cn/momoclouddisk/file/download?code=202203172024567_image.png)]

每个字母的父亲节点就是它的前一个字母

Trie树的三个性质:

  • 根节点不包含字符,除根节点外每一个节点都只包含一个字符
  • 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
  • 每个节点的所有子节点包含的字符都不相同

也就是按照各个词的前缀,将所有的词拆解组成一颗树的结构。

那么有了这样的一颗树,查找单词就变得很简单,从根节点开始向下匹配,如果匹配到单词的前缀就沿着该节点接着往下匹配,直到完全匹配到单词。

但是trie树的每个节点只能存储一个字符,这意味着面对较长的字符串仍然要向下探寻多个节点,这存在着浪费,因此就有了压缩字典树

压缩字典树,是trie树的一种,也称单词查找树、前缀树,善于进行字符串的检索、取字符串最长公共前缀、以及排序,常应用在搜索引擎中例如百度输入某个字可能自动弹出能匹配到的单词出来。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OFN2tQ7X-1650874176286)(https://www.hengyumo.cn/momoclouddisk/file/download?code=202203172031270_image.png)]

下面分别是/,/bear,/bell,/bid,/bull,/buy,/sell,/stock,/stop 的标准tire 和压缩 tire

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pDZBVYG2-1650874176286)(https://www.hengyumo.cn/momoclouddisk/file/download?code=202203172031771_image.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7dKRQ8CN-1650874176286)(https://www.hengyumo.cn/momoclouddisk/file/download?code=202203172032748_image.png)]

压缩字典树的特质使得其用于单词前缀查找时更快。这也恰巧就是一个高性能的路由匹配算法需要的。因此Gin使用其作为路由算法。

gin的压缩trie树结构如下:


type node struct {
	path      string // 存储着节点的字符串
	indices   string // 存储着下级子节点的前缀索引
	wildChild bool   
	nType     nodeType 
// nType 节点类型:
// static nodeType = iota // default,默认类型
// root 根节点
// param 参数,例如:id这样的通配符
// catchAll 全匹配
	priority  uint32  // 优先级
	children  []*node // 子节点, 至少有一个, :param 类型的节点会在列表的末尾
	handlers  HandlersChain // 匹配该节点的路由的处理函数
	fullPath  string        // 从根节点到该节点的完整路径
}

当使用gin注册路由时:

	g.Handle("GET", "/hi/:p", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "h*")
	})

就会调用addRoute向tire压缩树增加节点:

func (group *RouterGroup) handle(httpMethod, relativePath string, handlers HandlersChain) IRoutes {
	absolutePath := group.calculateAbsolutePath(relativePath)
	handlers = group.combineHandlers(handlers)
// 调用addRoute增加节点
	group.engine.addRoute(httpMethod, absolutePath, handlers)
	return group.returnObj()
}

在addRoute方法:

func (engine *Engine) addRoute(method, path string, handlers HandlersChain) {
// 校验路由格式
	assert1(path[0] == '/', "path must begin with '/'")
	assert1(method != "", "HTTP method can not be empty")
	assert1(len(handlers) > 0, "there must be at least one handler")

	debugPrintRoute(method, path, handlers)

// gin的路由不止是一颗tire树,而是一个method对应一颗tire树
	root := engine.trees.get(method)
	if root == nil {
// 初始化根节点
		root = new(node)
		root.fullPath = "/"
// 加到树的列表
		engine.trees = append(engine.trees, methodTree{method: method, root: root})
	}
// 将路由加到树里
	root.addRoute(path, handlers)

// 更新最大参数
	// Update maxParams
	if paramsCount := countParams(path); paramsCount > engine.maxParams {
		engine.maxParams = paramsCount
	}
// 更新'/'的最大个数
	if sectionsCount := countSections(path); sectionsCount > engine.maxSections {
		engine.maxSections = sectionsCount
	}
}

插入操作
下面图解一串子串插入压缩trie过程,/,/serach,/support,/blog , 在httprouter上截的一段例子,我们只插到/blog

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bUir07cI-1650874176287)(https://www.hengyumo.cn/momoclouddisk/file/download?code=202203172204388_image.png)]

插入/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lZQbJaKT-1650874176287)(https://www.hengyumo.cn/momoclouddisk/file/download?code=202203172205314_image.png)]

插入/serach
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U1QmzFcG-1650874176287)(https://www.hengyumo.cn/momoclouddisk/file/download?code=202203172205236_image.png)]

插入/support
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jNi5fsth-1650874176288)(https://www.hengyumo.cn/momoclouddisk/file/download?code=202203172205378_image.png)]

插入/blog
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-12URb9Xf-1650874176288)(https://www.hengyumo.cn/momoclouddisk/file/download?code=202203172206749_image.png)]

查询操作

1、先找共同前缀。
2、再找目录。
3、循环上面两步,直到当前path相等。

参考:https://blog.csdn.net/forever_dreams/article/details/81009580
https://blog.csdn.net/qq_17308321/article/details/89736691

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gin 框架原理 的相关文章

  • go的gin框架的性能测试

    最近可能想用用gin框架 xff0c 刚好在studygolang网站上看到一篇文章 xff0c 一个小伙测试gin的性能 所以想看看性能 我想把php xff0c 原生的golang的http包 xff0c gin框架一起在本地做个测试
  • go web gin框架实战1

    文章目录 go web gin框架实战1 参考资料2 demo3 demo运行4 demo解析 go web gin框架实战 1 参考资料 gin框架官方文档 链接 2 demo span class token keyword packa
  • 9-gin使用websocket

    toc gin使用websocket Gin 框架默认不支持 websocket xff0c 可以使用 github com gorilla websocket 实现 Talk is cheap Show me the code xff0c
  • Re 40:读论文 GL-GIN: Fast and Accurate Non-Autoregressive Model for Joint Multiple Intent Detection and

    诸神缄默不语 个人CSDN博文目录 论文名称 xff1a GL GIN Fast and Accurate Non Autoregressive Model for Joint Multiple Intent Detection and S
  • go的gin框架的性能测试

    最近可能想用用gin框架 xff0c 刚好在studygolang网站上看到一篇文章 xff0c 一个小伙测试gin的性能 所以想看看性能 我想把php xff0c 原生的golang的http包 xff0c gin框架一起在本地做个测试
  • Golang

    欢迎关注 全栈工程师修炼指南 公众号 点击 下方卡片 即可关注我哟 设为 星标 每天带你 基础入门 到 进阶实践 再到 放弃学习 专注 企业运维实践 网络安全 系统运维 应用开发 物联网实战 全栈文章 等知识分享 花开堪折直须折 莫待无花空
  • 使用 docker 容器化 Go-Gin 应用程序!

    文章目录 介绍 先决条件 构建 Gin 框架应用程序 创建 Dockerfile 构建 Docker 镜像 运行 Docker 容器 结论 使用 docker 容器化 Go Gin 应用程序 马赫什瓦尔 利加德的照片 马赫什瓦尔 利加德 1
  • go语言使用gin框架

    gin框架基础用法 package main import github com gin gonic gin net http func main router gin Default router LoadHTMLGlob templat
  • Go【gin和gorm框架】实现紧急事件登记的接口

    简单来说 就是接受前端微信小程序发来的数据保存到数据库 这是我写的第二个接口 相比前一个要稍微简单一些 而且因为前端页面也是我写的 参数类型自然是无缝对接 前端页面大概长这个样子 先用apifox模拟发送请求测试 apifox可以直接复制J
  • Gin微服务框架_golang web框架_完整示例Demo

    Gin简介 前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住分享一下给大家 点击跳转到网站 Gin是一个golang的微框架 封装比较优雅 API友好 源码注释比较明确 具有快速灵活 容错方便等特点 其实对于golang而
  • golang的web框架Gin(一)---Gin的安装与初体验

    简介 1 1 介绍 Go世界里最流行的Web框架 Github上有32K star 基于httprouter开发的Web框架 中文文档齐全 简单易用的轻量级框架 Gin是一个golang的微框架 封装比较优雅 API友好 源码注释比较明确
  • go 进阶 gin底层原理相关: 四. gin中间件底层原理

    目录 一 gin 中间件基础 二 中间件初始化流程 1 初始化中间件保存到RouterGroup的HandlersChain数组中 HandlersChain是什么 2 整合中间件函数与业务相关的mainHandler构建前缀树 三 中间件
  • gin 六.重定向路由重定向与请求转发

    目录 一 重定向与请求转发基础解释 二 重定向 gin Context Redirect 内部 外部重定向 路由重定向 三 请求转发 一 重定向与请求转发基础解释 重定向和请求转发是两种常见的HTTP请求处理方式 它们都可以实现将请求从一个
  • golang web开发

    目录 文章目录 前言 一 golang web是什么 二 搭建流程 1 模块划分 2 详细开发步骤 总结 前言 例如 习惯了java springboot 开发方式 比较疑惑golang web开发的流程和模块化的区分 就golang we
  • gin-巧用Context传递多种参数

    目录 引言 1 巧妙包装gin Context为NewContext 2 在使用gin Use对每一个请求的Context进行组装 3 在路由绑定时解析出NewContext来为应用层函数提供参数 并且调用应用层函数 4 总结 引言 首先给
  • Gin中的Cookie和Session的用法

    Gin中的Cookie和Session的用法 文章目录 Gin中的Cookie和Session的用法 介绍 Cookie 代码演示 Session 代码展示 介绍 cookie 和 session 是 Web 开发中常用的两种技术 主要用于
  • gin 三.请求数据的映射

    数据解析绑定 基础解释 ShouldBindWith 请求数据映射示例 ShouldBindHeader 将请求头绑定到一个结构体或接口示例 MustBindWith 方式 基础解释 解释 例如后端获取调用方参数 通常会使用一个结构体 或一
  • Golang gin 框架在中间件中获取请求和响应的各种数据

    为 gin 框架做不同用途的中间件时一般都需要获取到请求体和响应体的一些数据 例如做签名插件需要获取到请求参数 请求内容和 header 做鉴权插件需要获取到 header 的某些值 做日志插件需要的数据就更多了 下面就使用代码演示各种数据
  • 安装gin失败或卡住,亲测有效!

    安装gin失败或卡住 亲测有效 本人基于最近学习完了go所有语法 对go框架进一步学习与实战 但第一步的安装就遇到了坑 也是坑了很久 网上很多的方法 但是都乱七八糟 最主要一点毛线用都没有 柳暗花明又一村 功夫不负有心人 还是让我找到了解决
  • 48.Go简要实现令牌桶限流与熔断器并集成到Gin框架中

    文章目录 一 简介 二 限流器与熔断器在微服务中的作用 1 限流器 对某个接口单位时间内的访问量做限制 2 熔断器 当服务连续报错 超过一定阈值时 打开熔断器使得服务不可用 三 具体实现 1 限流器实现逻辑 以令牌桶算法为例 2 限流器集成

随机推荐

  • WSL2运行sudo gnome-session没反应

    必须注意当前用户 xff0c 不一定是在root下创建的gnome session xff0c 以我为例 xff0c 我当时是在leo用户下安装的gnome session xff0c 但之后一直都是以root用户登录 xff0c 所以运行
  • n个人围成一圈,第一个开始报数(1-3),凡报数3退出。问最后留下的人是原来第几号?

    include lt stdio h gt int main int i 61 0 j 61 0 k 61 0 n x int a 100 printf 34 please input a nu 34 scanf 34 d 34 amp n
  • 使用sea-orm执行migrate

    源码github地址 seaormdemo 一 下载工具链 sea orm cli 是sea orm 提供的工具链 xff0c 可通过cargo下载 cargo span class token function install span
  • PVE安装更新源错误

    pve系统ping 网络不通且不能进行apt install 描述 root 64 xuyuquan span class token comment apt get update span Err 1 http ftp debian or
  • failed to run command ‘java’: No such file or directory

    failed to run command java No such file or directory 程序里远程执行shell命令 xff08 nohup java jar xff09 的执行 xff0c 后台日志报错如下 xff1a
  • vue3中的setup函数

    原文 xff1a vue3中的setup函数 落雪小轩韩的博客 CSDN博客 vue3setup 一 概念 xff1a setup是vue3中的一个新的配置项 xff0c 值为一个函数 xff0c 我们在组件中用到的数据 方法等等 xff0
  • vue同步请求

    原文地址 xff1a vue 同步请求 Aa duidui的博客 CSDN博客 vue同步请求 同步请求执行的顺序 async await 挂上的才是同步 没挂上的还是异步 async 方法名 await 请求方法 参数 then res
  • Anaconda上设置虚拟环境,并在jupyter notebook中切换。

    个人记录 xff0c 但欢迎阅读和赐教 我之前在Anaconda Navigator中建立虚拟环境 xff0c 然后在jupyter notebook的terminal中增加对应环境的ipykernel xff0c 这样可行 xff0c 但
  • 字符,字节和编码

    级别 xff1a 初级 摘要 xff1a 本文介绍了字符与编码的发展过程 xff0c 相关概念的正确理解 举例说明了一些实际应用中 xff0c 编码的实现方法 然后 xff0c 本文讲述了通常对字符与编码的几种误解 xff0c 由于这些误解
  • http协议原理

    HTTP工作原理 HTTP协议定义Web客户端如何从Web服务器请求Web页面 xff0c 以及服务器如何把Web页面传送给客户端 HTTP协议采用了请求 响应模型 客户端向服务器发送一个请求报文 xff0c 请求报文包含请求的方法 URL
  • TLS协议/SSL协议

    历史背景 SSL Secure Socket Layer 安全套接层 是基于HTTPS下的一个协议加密层 xff0c 最初是由网景公司 xff08 Netscape xff09 研发 xff0c 后被IETF xff08 The Inter
  • TCP协议

    TCP 基础 https www jianshu com p ef892323e68f TCP 使用固定的连接 TCP 用于应用程序之间的通信 当应用程序希望通过 TCP 与另一个应用程序通信时 xff0c 它会发送一个通信请求 这个请求必
  • UDP协议

    UDP 概述 xff08 User Datagram Protocol xff0c 用户数据报协议 xff09 用户数据报协议 UDP 只在 IP 的数据报服务之上增加了很少一点的功能 xff0c 这就是复用和分用的功能以及查错检测的功能
  • TCP和UDP的区别

    TCP协议与UDP协议的区别 首先咱们弄清楚 xff0c TCP协议和UDP协议与TCP IP协议的联系 xff0c 很多人犯糊涂了 xff0c 一直都是说TCP协议与UDP协议的区别 xff0c 我觉得这是没有从本质上弄清楚网络通信 xf
  • 网络协议概述

    互联网协议介绍 互联网的核心是一系列协议 xff0c 总称为 互联网协议 xff08 Internet Protocol Suite xff09 xff0c 正是这一些协议规定了电脑如何连接和组网 我们理解了这些协议 xff0c 就理解了互
  • go 编写tcp和udp服务端和客户端

    TCP协议 TCP IP Transmission Control Protocol Internet Protocol 即传输控制协议 网间协议 xff0c 是一种面向连接 xff08 连接导向 xff09 的 可靠的 基于字节流的传输层
  • tcp黏包问题

    服务端代码如下 xff1a span class token keyword package span main span class token keyword import span span class token punctuati
  • go sync.Pool 深入

    new函数的调用时机和pool的内存释放规则 以下代码调用了四次Get函数 xff0c 但是并不是每次都会new 第一次 xff0c 是a 61 pool Get byte xff0c 首次Get xff0c 在pool的private私有
  • 【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)

    深入理解扩散模型 xff1a Diffusion Models 引言扩散模型的原理扩散过程反向过程优化目标 模型设计代码实现Stable Diffusion DALL E Imagen背后共同的套路Stable DiffusionDALL
  • gin 框架原理

    Gin的路由原理 Gin的路由基于Trie树和压缩字典树算法 xff0c 什么是Trie树 xff1f 其实很好理解 xff0c 看下图 xff1a 单词at xff0c bee xff0c ben xff0c bt xff0c q组成的T