Skip to content

Instantly share code, notes, and snippets.

@ShiSheng233
Last active January 1, 2023 03:04
Show Gist options
  • Save ShiSheng233/8deaad80f013487a9c1e29929d8acb94 to your computer and use it in GitHub Desktop.
Save ShiSheng233/8deaad80f013487a9c1e29929d8acb94 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
)
const blockSize = 8192 // 每个块的大小,单位为字节
// Block represents a block of data in the cache.
type Block struct {
data []string // 数据块中的行
idx map[int64]int // 索引,记录行在数据块中的位置
}
// DiskCache represents a cache of data stored on disk.
type DiskCache struct {
blocks map[int64]*Block // 块的编号与数据块的映射
idx map[int64]int // 索引,记录行所在的块编号
}
// NewDiskCache returns a new DiskCache.
func NewDiskCache() *DiskCache {
return &DiskCache{
blocks: make(map[int64]*Block),
idx: make(map[int64]int),
}
}
// Add adds a line to the cache.
func (dc *DiskCache) Add(line string) {
// 将行拆分成字段
fields := strings.Split(line, "----")
if len(fields) != 2 {
return
}
// 将字段1和字段2转换为数字
field1, err := strconv.ParseInt(fields[0], 10, 64)
if err != nil {
return
}
field2, err := strconv.ParseInt(fields[1], 10, 64)
if err != nil {
return
}
// 计算块编号
blockNum := field1 / blockSize
// 获取数据块
block, ok := dc.blocks[blockNum]
if !ok {
// 创建新的数据块
block = &Block{
data: make([]string, 0, blockSize),
idx: make(map[int64]int),
}
dc.blocks[blockNum] = block
}
// 将行添加到数据块
block.data = append(block.data, line)
block.idx[field1] = len(block.data) - 1
block.idx[field2] = len(block.data) - 1
}
// Get retrieves a line from the cache.
func (dc *DiskCache) Get(field int64) (string, bool) {
// 计算块编号
blockNum := field / blockSize
// 获取数据块
block, ok := dc.blocks[blockNum]
if !ok {
// 块不存在,返回空字符串和false
return "", false
}
// 查询索引
idx, ok := block.idx[field]
if !ok {
// 行不存在,返回空字符串和false
return "", false
}
// 返回行和true
return block.data[idx], true
}
func main() {
if len(os.Args) < 3 {
log.Println("HashMapQuirer: Not enough arguments\n\nUsage: .\\HashMapQuirer <File> <QueryParam>")
return
}
// 创建磁盘缓存
dc := NewDiskCache()
// 打开文件
file, err := os.Open(os.Args[1])
if err != nil {
log.Println("Error opening file:", err)
return
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
}
}(file)
// 创建文件扫描器
scanner := bufio.NewScanner(file)
// 逐行读取文件
for scanner.Scan() {
// 将行添加到磁盘缓存
dc.Add(scanner.Text())
}
// 检查是否遇到了错误
if err := scanner.Err(); err != nil {
log.Println("Error reading file:", err)
return
}
// 读取查询字段
var field int64
field, _ = strconv.ParseInt(os.Args[2], 10, 64)
log.Print("Enter the file to search for: " + os.Args[2])
// 查询磁盘缓存
line, ok := dc.Get(field)
if !ok {
log.Println("Line not found")
return
}
log.Println("Get: " + os.Args[1] + " <-> " + line)
fmt.Scanln()
}
@ShiSheng233
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment