1 回答

TA貢獻1796條經(jīng)驗 獲得超7個贊
您是否發(fā)現(xiàn)上述兩個計劃更改中的任何一個存在任何問題?這些是一個好的起點嗎?
兩者都沒有問題。如果日志肯定是行分隔的,您可以只存儲行號,但存儲字節(jié)偏移量可能更健壯。標(biāo)準(zhǔn)io.Reader接口返回讀取的字節(jié)數(shù),因此您可以使用它來獲得偏移量。
對于優(yōu)化我們?nèi)绾未鎯θ罩拘械膬?nèi)存消耗,您還有其他提示/建議嗎?
這取決于您想將它們用于什么目的,但是一旦它們被標(biāo)記化(并且您已經(jīng)從該行獲得了您想要的數(shù)據(jù)),為什么要在內(nèi)存中保留該行?它已經(jīng)在文件中,您現(xiàn)在有一個偏移量可以快速再次查找它。
除了枚舉之外,是否有任何等效于咆哮的位圖?或者任何其他巧妙的方式來緊湊地存儲它?
我傾向于將每個枚舉類型定義為一個 int,并使用iota. 就像是:
package main
import (
"fmt"
"time"
)
type LogLevel int
type LogComponent int
type Operation int
const (
Info LogLevel = iota
Warning
Debug
Error
)
const (
Storage LogComponent = iota
Journal
Commands
Indexin
)
const (
Query Operation = iota
Insert
Delete
)
type LogLine struct {
DateTime time.Time
QueryDuration time.Duration
ThreadName string
ConNum uint
Level LogLevel
Comp LogComponent
Op Operation
Namespace string
}
func main() {
l := &LogLine{
time.Now(),
10 * time.Second,
"query1",
1000,
Info,
Journal,
Delete,
"ns1",
}
fmt.Printf("%v\n", l)
}
產(chǎn)生&{2009-11-10 23:00:00 +0000 UTC 10s query1 1000 0 1 2 ns1}.
操場
您可以打包一些結(jié)構(gòu)體字段,但是您需要為每個字段定義位范圍,并且您會失去一些開放性。例如,將 LogLevel 定義為前 2 位,將 Component 定義為下 2 位等。
我還想到了布隆過濾器,也許使用它們來存儲每個日志行是否在一個集合中(即日志級別警告、日志級別錯誤)——但是,它只能在這些集合中,所以我不知道那講得通。另外,不確定如何處理誤報。
對于您當(dāng)前的示例,布隆過濾器可能有點矯枉過正。為每個枚舉或其他一些跟蹤行號到(例如)日志級別關(guān)系的主“索引”設(shè)置一個 []int 可能更容易。正如您所說,每個日志行只能在一組中。事實上,根據(jù)枚舉字段的數(shù)量,使用打包的枚舉作為標(biāo)識符可能更容易map[int][]int。
Set := make(map[int][]int)
Set[int(Delete) << 4 + int(Journal) << 2 + int(Debug)] = []int{7, 45, 900} // Line numbers in this set.
見這里為一個完整的,雖然hackish的例子。
- 1 回答
- 0 關(guān)注
- 237 瀏覽
添加回答
舉報