diff --git a/graph/graph.go b/graph/graph.go index 9ebfc3daa6..eeac8ecd27 100644 --- a/graph/graph.go +++ b/graph/graph.go @@ -40,7 +40,7 @@ func NewGraph(root string, driver graphdriver.Driver) (*Graph, error) { graph := &Graph{ Root: abspath, - idIndex: utils.NewTruncIndex(), + idIndex: utils.NewTruncIndex([]string{}), driver: driver, } if err := graph.restore(); err != nil { @@ -54,12 +54,14 @@ func (graph *Graph) restore() error { if err != nil { return err } + var ids = []string{} for _, v := range dir { id := v.Name() if graph.driver.Exists(id) { - graph.idIndex.Add(id) + ids = append(ids, id) } } + graph.idIndex = utils.NewTruncIndex(ids) utils.Debugf("Restored %d elements", len(dir)) return nil } diff --git a/runtime/runtime.go b/runtime/runtime.go index 98903cfa08..d612b48de0 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -779,7 +779,7 @@ func NewRuntimeFromDirectory(config *daemonconfig.Config, eng *engine.Engine) (* containers: list.New(), graph: g, repositories: repositories, - idIndex: utils.NewTruncIndex(), + idIndex: utils.NewTruncIndex([]string{}), sysInfo: sysInfo, volumes: volumes, config: config, diff --git a/utils/utils.go b/utils/utils.go index 1fe2e87b4f..8b6db8c464 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -426,12 +426,17 @@ type TruncIndex struct { bytes []byte } -func NewTruncIndex() *TruncIndex { - return &TruncIndex{ - index: suffixarray.New([]byte{' '}), +func NewTruncIndex(ids []string) (idx *TruncIndex) { + idx = &TruncIndex{ ids: make(map[string]bool), bytes: []byte{' '}, } + for _, id := range ids { + idx.ids[id] = true + idx.bytes = append(idx.bytes, []byte(id+" ")...) + } + idx.index = suffixarray.New(idx.bytes) + return } func (idx *TruncIndex) Add(id string) error { diff --git a/utils/utils_test.go b/utils/utils_test.go index 177d3667e1..501ae67c2c 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -138,7 +138,8 @@ func TestRaceWriteBroadcaster(t *testing.T) { // Test the behavior of TruncIndex, an index for querying IDs from a non-conflicting prefix. func TestTruncIndex(t *testing.T) { - index := NewTruncIndex() + ids := []string{} + index := NewTruncIndex(ids) // Get on an empty index if _, err := index.Get("foobar"); err == nil { t.Fatal("Get on an empty index should return an error") @@ -218,6 +219,25 @@ func assertIndexGet(t *testing.T, index *TruncIndex, input, expectedResult strin } } +func BenchmarkTruncIndexAdd(b *testing.B) { + ids := []string{"banana", "bananaa", "bananab"} + b.ResetTimer() + for i := 0; i < b.N; i++ { + index := NewTruncIndex([]string{}) + for _, id := range ids { + index.Add(id) + } + } +} + +func BenchmarkTruncIndexNew(b *testing.B) { + ids := []string{"banana", "bananaa", "bananab"} + b.ResetTimer() + for i := 0; i < b.N; i++ { + NewTruncIndex(ids) + } +} + func assertKernelVersion(t *testing.T, a, b *KernelVersionInfo, result int) { if r := CompareKernelVersion(a, b); r != result { t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)