package rdf

import (
	
	
)

// arena packs many short strings — expanded prefixed-name IRIs, unescaped
// literals — into shared backing buffers and hands out substring views, so
// materializing N distinct strings costs about total_bytes/chunkSize allocations
// instead of one per string.
//
// It grows by allocating a fresh chunk when the current one is full; a live chunk
// is never reallocated, so views returned earlier stay valid. Each chunk is kept
// alive by the strings that point into it (the runtime tracks a string's data
// pointer), so the arena itself need not outlive parsing.
type arena struct {
	buf []byte
}

const arenaChunkSize = 1 << 16 // 64 KiB

// reserve ensures the current chunk holds at least n more bytes, starting a fresh
// chunk (never reallocating the live one) when it does not, and returns the offset
// at which writing begins.
func ( *arena) ( int) int {
	if cap(.buf)-len(.buf) <  {
		.buf = make([]byte, 0, max(, arenaChunkSize)) // old chunk stays alive via its views
	}
	return len(.buf)
}

// view returns the bytes appended since start as an arena-backed string.
func ( *arena) ( int) string {
	if len(.buf) ==  {
		return ""
	}
	 := .buf[:len(.buf):len(.buf)]
	return unsafe.String(&[0], len())
}

// concat returns x+y as an arena-backed string, allocating only when a new chunk
// is needed.
func ( *arena) (,  string) string {
	if len()+len() == 0 {
		return ""
	}
	 := .reserve(len() + len())
	.buf = append(.buf, ...)
	.buf = append(.buf, ...)
	return .view()
}

// bytesView returns b's bytes as a string without copying. The caller must not
// modify b while the string, or any substring of it, remains reachable — it is
// what backs the Shared parse variants.
func bytesView( []byte) string {
	if len() == 0 {
		return ""
	}
	return unsafe.String(&[0], len())
}

// unescape decodes the RDF string escapes in s into the arena. The unescaped form
// is never longer than s, so the single reservation never overflows the chunk.
func ( *arena) ( string) string {
	 := .reserve(len())
	for  := 0;  < len(); {
		if [] == '\\' && +1 < len() {
			,  := unescapeRune([:])
			.buf = utf8.AppendRune(.buf, )
			 += 
			continue
		}
		.buf = append(.buf, [])
		++
	}
	return .view()
}