// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fs

import (
	"sync"

	"github.com/libgit2/git2go"
)

type nodeCacheKey struct {
	ID   git.Oid
	xbit bool
}

// The nodeCache keeps a map of ID to FS node. It is safe for
// concurrent use from multiple goroutines. The cache allows us to
// reuse out the same node for multiple files, effectively
// hard-linking the file. This is done for two reasons: first, each
// blob takes up kernel FS cache memory only once, even if it may be
// used in multiple checkouts. Second, moving data from the FUSE
// process into the kernel is relatively expensive. Thus, we can
// amortize the cost of the read over multiple checkouts.
type nodeCache struct {
	mu      sync.RWMutex
	nodeMap map[nodeCacheKey]*gitilesNode
}

func newNodeCache() *nodeCache {
	return &nodeCache{
		nodeMap: make(map[nodeCacheKey]*gitilesNode),
	}
}

func (c *nodeCache) get(id *git.Oid, xbit bool) *gitilesNode {
	c.mu.RLock()
	defer c.mu.RUnlock()

	return c.nodeMap[nodeCacheKey{*id, xbit}]
}

func (c *nodeCache) add(n *gitilesNode) {
	xbit := n.mode&0111 != 0
	c.mu.Lock()
	defer c.mu.Unlock()

	c.nodeMap[nodeCacheKey{n.id, xbit}] = n
}
