package stmtcache

import (
	

	
)

// LRUCache implements Cache with a Least Recently Used (LRU) cache.
type LRUCache struct {
	cap          int
	m            map[string]*list.Element
	l            *list.List
	invalidStmts []*pgconn.StatementDescription
}

// NewLRUCache creates a new LRUCache. cap is the maximum size of the cache.
func ( int) *LRUCache {
	return &LRUCache{
		cap: ,
		m:   make(map[string]*list.Element),
		l:   list.New(),
	}
}

// Get returns the statement description for sql. Returns nil if not found.
func ( *LRUCache) ( string) *pgconn.StatementDescription {
	if ,  := .m[];  {
		.l.MoveToFront()
		return .Value.(*pgconn.StatementDescription)
	}

	return nil

}

// Put stores sd in the cache. Put panics if sd.SQL is "". Put does nothing if sd.SQL already exists in the cache.
func ( *LRUCache) ( *pgconn.StatementDescription) {
	if .SQL == "" {
		panic("cannot store statement description with empty SQL")
	}

	if ,  := .m[.SQL];  {
		return
	}

	if .l.Len() == .cap {
		.invalidateOldest()
	}

	 := .l.PushFront()
	.m[.SQL] = 
}

// Invalidate invalidates statement description identified by sql. Does nothing if not found.
func ( *LRUCache) ( string) {
	if ,  := .m[];  {
		delete(.m, )
		.invalidStmts = append(.invalidStmts, .Value.(*pgconn.StatementDescription))
		.l.Remove()
	}
}

// InvalidateAll invalidates all statement descriptions.
func ( *LRUCache) () {
	 := .l.Front()
	for  != nil {
		.invalidStmts = append(.invalidStmts, .Value.(*pgconn.StatementDescription))
		 = .Next()
	}

	.m = make(map[string]*list.Element)
	.l = list.New()
}

func ( *LRUCache) () []*pgconn.StatementDescription {
	 := .invalidStmts
	.invalidStmts = nil
	return 
}

// Len returns the number of cached prepared statement descriptions.
func ( *LRUCache) () int {
	return .l.Len()
}

// Cap returns the maximum number of cached prepared statement descriptions.
func ( *LRUCache) () int {
	return .cap
}

func ( *LRUCache) () {
	 := .l.Back()
	 := .Value.(*pgconn.StatementDescription)
	.invalidStmts = append(.invalidStmts, )
	delete(.m, .SQL)
	.l.Remove()
}