Rust开发——使用rust实现Redis中hset

一、Redis中hset

HSET 是 Redis 中用于在哈希数据结构中设置指定字段的值的命令。哈希是一种类似于字典或映射的数据结构,它存储了键值对的集合,其中每个键都包含多个字段和与这些字段相关联的值。

哈希表在 Redis 中以键值对形式存储,并通过唯一的键名来访问。每个键都可以关联多个字段和对应的值,这使得哈希表非常适合存储对象、实体或记录的属性。

HSET 命令的基本语法是:

HSET key field value
  • key 是哈希表的名称。
  • field 是要设置值的字段名称。
  • value 是要存储在字段中的值。

举例来说,假设我们有一个用户信息的哈希表,键为 user:1001,我们可以使用 HSET 命令来设置用户ID为 1001 的用户名为 johndoe

HSET user:1001 username johndoe

这个命令将在 user:1001 哈希表中的 username 字段设置值为 johndoe。之后,可以使用 HGET 命令来获取指定字段的值:

HGET user:1001 username

以上命令将返回 user:1001 哈希表中 username 字段的值,即 johndoe

哈希表的优势在于可以高效地存储和检索大量的字段-值对,特别适用于需要存储和查询对象属性的场景。除了 HSET 命令之外,Redis 还提供了其他与哈希表操作相关的命令,如 HGETALL 用于获取哈希表中所有字段和值的列表,HDEL 用于删除一个或多个字段等等。

二、Hset的应用

HSET 命令在 Redis 中有许多应用场景,特别是在需要存储和检索对象属性的情况下非常有用。以下是一些 HSET 命令在实际应用中的常见用例:

1. 存储用户信息

用于存储用户信息是 HSET 命令的常见用例之一。例如,存储用户的用户名、电子邮件、年龄等信息:

HSET user:1001 username johndoe
HSET user:1001 email john@example.com
HSET user:1001 age 30

2. 缓存对象属性

在缓存中存储对象属性是提高读取性能的一种方式。比如,存储商品信息:

HSET product:5001 name "Product Name"
HSET product:5001 price 29.99
HSET product:5001 category "Electronics"

3. 记录实时数据

用于记录实时数据的情况,例如实时监控系统中的指标数据:

HSET stats:today visits 1000
HSET stats:today purchases 50
HSET stats:today revenue 2500.00

4. 缓存对象状态

在缓存中存储对象状态或配置信息:

HSET server:status hostname "Server-A"
HSET server:status status "Running"
HSET server:status users_connected 50

5. 存储表单数据

在 Web 开发中,可以使用哈希表存储表单数据,比如用户提交的表单信息:

HSET form:submission:1001 name "Alice"
HSET form:submission:1001 email "alice@example.com"
HSET form:submission:1001 message "This is a sample message."

6. 对象属性索引

用于创建对象属性的索引,以便于检索和查询。例如,在数据库中存储用户的兴趣标签:

HSET interest:books user:1001 1
HSET interest:music user:1001 1
HSET interest:travel user:1001 1

哈希数据结构提供了灵活性和高效性,能够存储和管理多个字段和值,因此在许多需要键值对集合的场景中被广泛应用。

三、使用Rust实现Hset表

在Rust中,是没有Hset这具库API,如果想实现像Redis中hset,要自己动手实现,这里我想的实现的结构是记录一篇文章的评论,评论的ID,与回复评论的内容与ID,存储内容如下表:
在这里插入图片描述

实现代码:

use std::{collections::HashMap, borrow::Borrow};
use std::hash::Hash;

#[derive(Clone)]
pub struct Value<K,V>
{
    pub value : HashMap<K,V>,
}

impl <K,V> Value<K,V> 
{
    pub fn new() ->Self
    {
        Self { value: HashMap::new()}
    }
}

#[derive(Clone)]
pub struct Field<K,V>
{
    pub field : Value<K,V>,
    pub ex_field : HashMap<K,Value<K,V>>,
}

impl<K,V> Field<K,V>
{
    pub fn new() ->Self
    {
        Self { field: Value::new(), ex_field: HashMap::new()}
    }
}

#[derive(Clone,Default)]
pub struct HashSet<K,V>
{
   pub set : HashMap<K,Field<K,V>>,
}

impl<K,V> HashSet<K,V>
where
K:Hash + Eq,
V:Copy,
{
    pub fn new() ->Self
    {
        Self { set: HashMap::new()}
    }
    
    pub fn insert(&mut self, key : K, field : K, value : V,sub_field : Option<K>) ->bool
    {
        match sub_field
        {
            Some(ex_key) =>
            {
                match self.set.get_mut(&key)
                {
                    Some(f_value) =>
                    {
                        match f_value.ex_field.get_mut(&ex_key)
                        {
                            Some(ex_value) =>
                            {
                                match ex_value.value.get_mut(&field)
                                {
                                    Some(_ex) => false,
                                    None =>
                                    {
                                        ex_value.value.insert(field, value);
                                        true
                                    },
                                }
                            },
                            None =>
                            {
                                let mut sub : Value<K,V> = Value::new();
                                sub.value.insert(field, value);
                                f_value.ex_field.insert(ex_key,sub);
                                true
                            },
                        }
                    },
                    None =>
                    {
                        let mut sub : Value<K,V> = Value::new();
                        sub.value.insert(field, value);
                        let mut m_field : Field<K,V> = Field::new();
                        m_field.ex_field.insert(ex_key, sub);
                        self.set.insert(key, m_field);
                        true
                    },
                }
            },
            None =>
            {
                match self.set.get_mut(&key)
                {
                    Some(set) =>
                    {
                        match set.field.value.get_mut(&field)
                        {
                            Some(_v) => false,
                            None =>
                            {
                               set.field.value.insert(field, value);
                               true
                            }
                        }
                    },
                    None =>
                    {
                        let mut m_field : Field<K,V> = Field::new();
                        m_field.field.value.insert(field, value);
                        self.set.insert(key, m_field);
                        true
                    }
                }
            },
        }
    }

    pub fn remove(&mut self, key : K , field : K, sub_field : Option<K>)->bool
    {
        match sub_field
        {
            Some(ex_key) =>
            {
                match self.set.get_mut(&key)
                {
                    Some(f_value) =>
                    {
                        match f_value.ex_field.get_mut(&ex_key)
                        {
                            Some(ex_value) =>
                            {
                                match ex_value.value.get_mut(&field)
                                {
                                    Some(_ex) =>
                                    {
                                        ex_value.value.remove(&field);
                                        true
                                    }
                                    None => false,
                                }
                            },
                            None => false
                        }
                    },
                    None => false
                }
            },
            None =>
            {
                match self.set.get_mut(&key)
                {
                    Some(set) =>
                    {
                        match set.field.value.get_mut(&field)
                        {
                            Some(_v) =>
                            {
                                set.field.value.remove(&field);
                                true
                            },
                            None => false
                        }
                    },
                    None =>false
                }
            },
        }
    }

    pub fn get_field_value(&self,key : K, field : K) -> Result<V,bool>
    {
        match self.set.get(&key)
        {
            Some(value) =>
            {
                match value.field.value.get(&field)
                {
                    Some(v) => Ok(*v),
                    None => Err(false),
                }
            },
            None => Err(false)
        }
    }

    pub fn get_ex_field_value(&self,key:K, field : K,sub_field : K) ->Result<V,bool>
    {
        match self.set.get(&key)
        {
            Some(value) =>
            {
                match value.ex_field.get(&sub_field)  
                {
                    Some(sub_value) =>
                    {
                        match sub_value.value.get(&field)
                        {
                            Some(v) => Ok(*v),
                            None => Err(false),
                        }
                    }
                    None =>  Err(false)
                }
            }
            None => Err(false)
        }
    }
}

pub fn hset_size(hset : HashSet<&str,u64>) ->usize
{
    let mut size : usize = 0;
    for (k,v) in hset.set
    {
        let f_size = field_size(v);
        size += k.len() + f_size;
    }
    size
}

pub fn field_size(field : Field<&str,u64>) -> usize
{
    let mut f_size : usize = 0;
    for(m_k,_m_v) in field.field.value
    {
        f_size += m_k.len() + 8;
    }

    let mut ex_size : usize = 0;
    for(f_k,f_v) in field.ex_field
    {
        let mut sub_size : usize = 0;
        for (s_k, _s_v) in f_v.value.iter()
        {
            sub_size += s_k.len() + 8;
        }
        ex_size += sub_size + f_k.len();
    }

    f_size + ex_size    
}
use core::num;
use std::{mem, collections::{HashMap}, time::{SystemTime, UNIX_EPOCH}, borrow::{Borrow, BorrowMut}, cell::RefCell};

pub struct CanisterState
{
    data : HashSet<String,u64>,
}


fn main() 
{
     let v : Vec<u8> = vec![65];
     let m = String::from_utf8(v.clone()).unwrap();
     print!("{}\n",m);

     LIKES.with(|like_ref|
     {
         let hset : CanisterState  = CanisterState { data: mem::take(&mut like_ref.borrow_mut()) };
     });
    let mut hset : HashSet<&str,u64> = HashSet::new();
     hset.insert("唐诗", "王维",time(),Some("10"));
     hset.insert("唐", "李白",time(),None);
     hset.insert("诗", "李白",time(),None);
     hset.insert("宋", "李清照",time(),Some("1"));
     hset.insert("宋词", "李清照",time(),None);

     let r = hset.get_field_value("唐诗", "李白");
     match r
     {
         Ok(v) => print!("{}\n",v),
         Err(e) => print!("{}\n",e),
     }

      print!("{}\n",hset_size(hset.clone()));
	 let _ = hset.remove("matt", "200", None);

  
     hset.insert("matt".to_string(), "300".to_string(),
     "200".to_string(),None);
     hset.insert("matt".to_string(), "200".to_string(),
     "200".to_string(),None);

     hset.insert("45m".to_string(), "300".to_string(),
     "200".to_string(),None);
     hset.insert("45m".to_string(), "200".to_string(),
     "200".to_string(),None);
    /show(hset.clone());
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/155033.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【libGDX】ApplicationAdapter生命周期

1 前言 libGDX 中&#xff0c;用户自定义的渲染窗口需要继承 ApplicationAdapter 类&#xff0c;ApplicationAdapter 实现了 ApplicationListener 接口&#xff0c;但实现的方法都是空方法&#xff0c;方法释义如下。 public interface ApplicationListener {// 应用首次创建时…

java版工程管理系统Spring Cloud+Spring Boot+Mybatis实现工程管理系统源码

工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&am…

ArmV8常用汇编指令2

接上文&#xff0c;我们来分析一些具体指令。 1.加载存储指令 Load/Store可以分为立即数、寄存器等操作&#xff0c;格式如下&#xff1a; 这里Rn和Rt均为4位&#xff0c;原因在于&#xff0c;A32/T32是16个通用寄存器。因此使用4bit刚好可以遍历所有。如果是运行在AArch64&a…

Spring Task使用介绍

文章目录 Spring Task介绍cron表达式入门案例Spring Task使用步骤全注解的方式代码开发测试结果 代码仓库 Spring Task 介绍 Spring Task 是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代码逻辑。 定位定时任务框架 作用定时自动执行某段Java…

python爬虫概述及简单实践:获取豆瓣电影排行榜

目录 前言 Python爬虫概述 简单实践 - 获取豆瓣电影排行榜 1. 分析目标网页 2. 获取页面内容 3. 解析页面 4. 数据存储 5. 使用代理IP 总结 前言 Python爬虫是指通过程序自动化地对互联网上的信息进行抓取和分析的一种技术。Python作为一门易于学习且强大的编程语言&…

Ps:锁定图层

使用“图层”面板上的锁定图层 Lock Layer功能可以完全或部分锁定图层以保护其内容。 比如&#xff0c;在完成某个图层后希望它不再被修改&#xff08;包括不透明度和图层样式等&#xff09;&#xff0c;可将其完全锁定。 如果不想更改图像&#xff0c;但对其摆放位置还在犹豫不…

SpringBoot实现IP地址归属地查询

SpringBoot实现IP地址归属地查询 功能特性 标准化的数据格式 每个 IP 数据段的 region 信息都固定了格式&#xff1a; 国家|区域|省份|城市|ISP&#xff0c;只有中国的数据绝大部分精确到了城市&#xff0c;其他国家部分数据只能定位到国家&#xff0c;后前的选项全部是 0。…

6.运行mysql容器-理解容器数据卷

运行mysql容器-理解容器数据卷 1.什么是容器数据卷2.如何使用容器数据卷2.1 数据卷挂载命令2.2 容器数据卷的继承2.3 数据卷的读写权限2.4 容器数据卷的小实验&#xff08;加深理解&#xff09;2.4.1 启动挂载数据卷的centos容器2.4.2 启动后&#xff0c;在宿主机的data目录下会…

demo(三)eurekaribbonhystrix----服务降级熔断

一、介绍&#xff1a; 1、雪崩&#xff1a; 多个微服务之间调用的时候&#xff0c;假如微服务A调用微服务B和微服务C&#xff0c;微服务B和微服务C又调用其他的微服务&#xff0c;这就是所谓的"扇出"。如果扇出的链路上某个微服务的调用响应的时间过长或者不可用&am…

【flutter】使用getx下的GetMaterialApp创建路由和使用时间选择器国际化问题

GetMaterialApp是啥 网上解释说是 MaterialApp Getx properties GetMaterialApp 问题 在使用showDateRangePicker组件的时候&#xff0c; 一直报错 No MaterialLocalizations found 我就愁思是不是GetMaterialApp跟MaterialApp方法不一样的问题&#xff0c;结果不是&#…

【7】Spring Boot 3 集成组件:缓存组件 spring cache + spring data redis

目录 【7】Spring Boot 3 集成组件&#xff1a;缓存组件 spring cache spring data redis什么是缓存抽象声明式注解JSR-107对应SpEL上下文数据 引入依赖cache 支持的缓存类型缓存类型配置NONESIMPLEREDIS自定义配置 CAFFEINE Hazelcast...总结 个人主页: 【⭐️个人主页】 需要…

【第2章 Node.js基础】2.7 Node.js 的流(一) 可读流

&#x1f308; Node.js 的流 &#x1f680;什么是流 流不是 Node.js 特有的概念。它们是几十年前在 Unix 操作系统中引入的。 我们可以把流看作这些数据的集合&#xff0c;就像液体一样&#xff0c;我们先把这些液体保存在一个容器里&#xff08;流的内部缓冲区 BufferList&…

Windows SmartScreen中的漏洞!

&#x1f525;另一个流行漏洞是 CVE-2023-36025 - 绕过 Windows SmartScreen 安全功能&#xff0c;该功能是多个微软产品的网络钓鱼和恶意软件保护组件。 &#x1f47e;有多危险 利用该漏洞&#xff0c;攻击者可以绕过 Windows Defender SmartScreen 检查和相关警告。利用该漏…

【Python】Pandas(学习笔记)

一、Pandas概述 1、Pandas介绍 2008年WesMcKinney开发出的库&#xff0c;专门用于数据挖掘的开源python库 以Numpy为基础&#xff0c;借力Numpy模块在计算方面性能高的优势 基于matplotib&#xff0c;能够简便的画图 独特的数据结构 import pandas as pd2、Pandas优势 便…

Dart 3.2 更新,Flutter Web 的未来越来越明朗

参考原文&#xff1a;https://medium.com/dartlang/dart-3-2-c8de8fe1b91f 本次跟随 Flutter 3.16 发布 的 Dart 3.2 &#xff0c;包含有&#xff1a;私有 final 字段的非空改进、新的 interop 改进、对 DevTools 中的扩展支持、以及对 Web 路线图的更新&#xff0c;包括对 Was…

Unity开发之C#基础-集合(字典)(Dictionary)

前言 Hello 兄弟们 一转眼俩月又过去了&#xff08;失踪人口回归&#xff09; 不出意外的是出意外了 失踪了两个月 有点对不起我这为数不多的粉丝们 实不相瞒忙的焦头烂额 也没心情写博客 实在对不住各位 好了长话短说 今天这篇文章是讲解c#当中的新的一种集合的表现&#xff…

ProtocolBuffers(protobuf)详解

目录 前言特点语法定义关键字JSON与Protocol Buffers互相转换gRPC与Protocol Buffers的关系 前言 Protocol Buffers&#xff08;通常简称为protobuf&#xff09;是Google公司开发的一种数据描述语言&#xff0c;它能够将结构化数据序列化&#xff0c;可用于数据存储、通信协议…

pip 问题

升级pip命令&#xff1a; python -m pip install --upgrade pippip不能下载pytorch&#xff1a; 这个问题我一直没解决。不知道有哪位大佬可以留言给我。把whl文件下载到本地也没有&#xff0c;pip不会进行本地文件夹搜索。

园区网络项目实战

实验背景 某写字楼备搭建一张网络供楼内企业办公使用。写字楼共6层&#xff0c;目前已有三层投入使用&#xff0c;分别 是一层会客大厅、二层行政部及总经理办公室、三层研发部和市场部。一层设有核心机房&#xff0c;其 他各楼层均有一个小房间放置网络设备。 第一步 询…

程序员如何悄悄拔尖,然后惊艳四座?

谁最初还不是个血气方刚、胸怀抱负的有志青年了&#xff1f; 渐渐的&#xff0c;被岁月磨平棱角&#xff0c;被生活冲淡理想&#xff0c;如今的你还有几分似从前&#xff1f; 你是否&#xff0c;不安现状、焦虑未来、忙忙碌碌没有方向&#xff1f; 不甘平庸?不想摸鱼&#…