Last active
January 1, 2023 03:04
-
-
Save ShiSheng233/8deaad80f013487a9c1e29929d8acb94 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Get the prebuilt files from:
https://oss.shisheng.icu/Code/HMQ/HashMapQuirer
https://oss.shisheng.icu/Code/HMQ/HashMapQuirer.exe