/*
 * SPDX-FileCopyrightText: © Hypermode Inc. <hello@hypermode.com>
 * SPDX-License-Identifier: Apache-2.0
 */

package z

import (
	
	

	
)

type Key interface {
	uint64 | string | []byte | byte | int | int32 | uint32 | int64
}

// TODO: Figure out a way to re-use memhash for the second uint64 hash,
// we already know that appending bytes isn't reliable for generating a
// second hash (see Ristretto PR #88).
// We also know that while the Go runtime has a runtime memhash128
// function, it's not possible to use it to generate [2]uint64 or
// anything resembling a 128bit hash, even though that's exactly what
// we need in this situation.
func [ Key]( ) (uint64, uint64) {
	 := any()
	switch k := .(type) {
	case uint64:
		return , 0
	case string:
		return MemHashString(), xxhash.Sum64String()
	case []byte:
		return MemHash(), xxhash.Sum64()
	case byte:
		return uint64(), 0
	case int:
		return uint64(), 0
	case int32:
		return uint64(), 0
	case uint32:
		return uint64(), 0
	case int64:
		return uint64(), 0
	default:
		panic("Key type not supported")
	}
}

var (
	dummyCloserChan <-chan struct{}
	tmpDir          string
)

// Closer holds the two things we need to close a goroutine and wait for it to
// finish: a chan to tell the goroutine to shut down, and a WaitGroup with
// which to wait for it to finish shutting down.
type Closer struct {
	waiting sync.WaitGroup

	ctx    context.Context
	cancel context.CancelFunc
}

// SetTmpDir sets the temporary directory for the temporary buffers.
func ( string) {
	tmpDir = 
}

// NewCloser constructs a new Closer, with an initial count on the WaitGroup.
func ( int) *Closer {
	 := &Closer{}
	.ctx, .cancel = context.WithCancel(context.Background())
	.waiting.Add()
	return 
}

// AddRunning Add()'s delta to the WaitGroup.
func ( *Closer) ( int) {
	.waiting.Add()
}

// Ctx can be used to get a context, which would automatically get cancelled when Signal is called.
func ( *Closer) () context.Context {
	if  == nil {
		return context.Background()
	}
	return .ctx
}

// Signal signals the HasBeenClosed signal.
func ( *Closer) () {
	// Todo(ibrahim): Change Signal to return error on next badger breaking change.
	.cancel()
}

// HasBeenClosed gets signaled when Signal() is called.
func ( *Closer) () <-chan struct{} {
	if  == nil {
		return dummyCloserChan
	}
	return .ctx.Done()
}

// Done calls Done() on the WaitGroup.
func ( *Closer) () {
	if  == nil {
		return
	}
	.waiting.Done()
}

// Wait waits on the WaitGroup. (It waits for NewCloser's initial value, AddRunning, and Done
// calls to balance out.)
func ( *Closer) () {
	.waiting.Wait()
}

// SignalAndWait calls Signal(), then Wait().
func ( *Closer) () {
	.Signal()
	.Wait()
}

// ZeroOut zeroes out all the bytes in the range [start, end).
func ( []byte, ,  int) {
	if  < 0 ||  >= len() {
		return // BAD
	}
	if  >= len() {
		 = len()
	}
	if - <= 0 {
		return
	}
	Memclr([:])
	// b := dst[start:end]
	// for i := range b {
	// 	b[i] = 0x0
	// }
}