text:
package flate

import (
	"fmt"
	"io"
	"math"
)

const (
	NoCompression       = 0
	BestSpeed           = 1
	BestCompression     = 9
	DefaultCompression  = -1
	ConstantCompression = -2 // Does only Huffman encoding
	logWindowSize       = 15
	windowSize          = 1 << logWindowSize
	windowMask          = windowSize - 1
	logMaxOffsetSize    = 15  // Standard DEFLATE
	minMatchLength      = 4   // The smallest match that the compressor looks for
	maxMatchLength      = 258 // The longest match for the compressor
	minOffsetSize       = 1   // The shortest offset that makes any sense

	// The maximum number of tokens we put into a single flat block, just too
	// stop things from getting too large.
	maxFlateBlockTokens = 1 << 14
	maxStoreBlockSize   = 65535
	hashBits            = 17 // After 17 performance degrades
	hashSize            = 1 << hashBits
	hashMask            = (1 << hashBits) - 1
	hashShift           = (hashBits + minMatchLength - 1) / minMatchLength
	maxHashOffset       = 1 << 24

	skipNever = math.MaxInt32
)

var useSSE42 bool

type compressionLevel struct {
	good, lazy, nice, chain, fastSkipHashing, level int
}

// Compression levels have been rebalanced from zlib deflate defaults
// to give a bigger spread in speed and compression.
// See https://blog.klauspost.com/rebalancing-deflate-compression-levels/
var levels = []compressionLevel{
	{}, // 0
	// Level 1+2 uses snappy algorithm - values not used
	{0, 0, 0, 0, 0, 1},
	{0, 0, 0, 0, 0, 2},
	// For levels 3-6 we don't bother trying with lazy matches.
	// Lazy matching is at least 30% slower, with 1.5% increase.
	{4, 0, 8, 4, 4, 3},
	{4, 0, 12, 6, 5, 4},
	{6, 0, 24, 16, 6, 5},
	{8, 0, 32, 32, 7, 6},
	// Levels 7-9 use increasingly more lazy matching
	// and increasingly stringent conditions for "good enough".
	{4, 8, 16, 16, skipNever, 7},
	{6, 16, 32, 64, skipNever, 8},
	{32, 258, 258, 4096, skipNever, 9},
}

type hashid uint32

type compressor struct {
	compressionLevel

	w          *huffmanBitWriter
	bulkHasher func([]byte, []hash)

	// compression algorithm
	fill func(*compressor, []byte) int // copy data to window
	step func(*compressor)             // process window
	sync bool                          // requesting flush

	// Input hash chains
	// hashHead[hashValue] contains the largest inputIndex with the specified hash value
	// If hashHead[hashValue] is within the current window, then
	// hashPrev[hashHead[hashValue] & windowMask] contains the previous index
	// with the same hash value.
	chainHead  int
	hashHead   []hashid
	hashPrev   []hashid
	hashOffset int

	// input window: unprocessed data is window[index:windowEnd]
	index         int
	window        []byte
	windowEnd     int
	blockStart    int  // window index where current tokens start
	byteAvailable bool // if true, still need to process window[index-1].

	// queued output tokens
	tokens tokens

	// deflate state
	length         int
	offset         int
	hash           hash
	maxInsertIndex int
	err            error
	ii             uint16 // position of last match, intended to overflow to reset.

	snap      snappyEnc
	hashMatch [maxMatchLength + minMatchLength]hash
}

type hash int32

func (d *compressor) fillDeflate(b []byte) int {
	if d.index >= 2*windowSize-(minMatchLength+maxMatchLength) {
		// shift the window by windowSize
		copy(d.window, d.window[windowSize:2*windowSize])
		d.index -= windowSize
		d.windowEnd -= windowSize
		if d.blockStart >= windowSize {
			d.blockStart -= windowSize
		} else {
			d.blockStart = math.MaxInt32
		}
		d.hashOffset += windowSize
		if d.hashOffset > maxHashOffset {
			delta := d.hashOffset - 1
			d.hashOffset -= delta
			d.chainHead -= delta
			for i, v := range d.hashPrev {
				if int(v) > delta {
					d.hashPrev[i] = hashid(int(v) - delta)
				} else {
					d.hashPrev[i] = 0
				}
			}
			for i, v := range d.hashHead {
				if int(v) > delta {
					d.hashHead[i] = hashid(int(v) - delta)
				} else {
					d.hashHead[i] = 0
				}
			}
		}
	}
	n := copy(d.window[d.windowEnd:], b)
	d.windowEnd += n
	return n
}

func (d *compressor) writeBlock(tok tokens, index int, eof bool) error {
	if index > 0 || eof {
		var window []byte
		if d.blockStart <= index {
			window = d.window[d.blockStart:index]
		}
		d.blockStart = index
		d.w.writeBlock(tok, eof, window)
		return d.w.err
	}
	return nil
}

// writeBlockSkip writes the current block and uses the number of tokens
// to determine if the block should be stored on no matches, or
// only huffman encoded.
func (d *compressor) writeBlockSkip(tok tokens, index int, eof bool) error {
	if index > 0 || eof {
		if d.blockStart <= index {
			window := d.window[d.blockStart:index]
			if tok.n == len(window) && !eof {
				d.writeStoredBlock(window)
				// If we removed less than 10 literals, huffman compress the block.
			} else if tok.n > len(window)-10 {
				d.w.writeBlockHuff(eof, window)
			} else {
				// Write a dynamic huffman block.
				d.w.writeBlockDynamic(tok, eof, window)
			}
		} else {
			d.w.writeBlock(tok, eof, nil)
		}
		d.blockStart = index
		return d.w.err
	}
	return nil
}

// fillWindow will fill the current window with the supplied
// dictionary and calculate all hashes.
// This is much faster than doing a full encode.
// Should only be used after a start/reset.
func (d *compressor) fillWindow(b []byte) {
	// Do not fill window if we are in store-only mode,
	// use constant or Snappy compression.
	switch d.compressionLevel.level {
	case 0, 1, 2:
		return
	}
	// If we are given too much, cut it.
	if len(b) > windowSize {
		b = b[len(b)-windowSize:]
	}
	// Add all to window.
	n := copy(d.window[d.windowEnd:], b)

	// Calculate 256 hashes at the time (more L1 cache hits)
	loops := (n + 256 - minMatchLength) / 256
	for j := 0; j < loops; j++ {
		startindex := j * 256
		end := startindex + 256 + minMatchLength - 1
		if end > n {
			end = n
		}
		tocheck := d.window[startindex:end]
		dstSize := len(tocheck) - minMatchLength + 1

		if dstSize <= 0 {
			continue
		}

		dst := d.hashMatch[:dstSize]
		d.bulkHasher(tocheck, dst)
		var newH hash
		for i, val := range dst {
			di := i + startindex
			newH = val & hashMask
			// Get previous value with the same hash.
			// Our chain should point to the previous value.
			d.hashPrev[di&windowMask] = d.hashHead[newH]
			// Set the head of the hash chain to us.
			d.hashHead[newH] = hashid(di + d.hashOffset)
		}
		d.hash = newH
	}
	// Update window information.
	d.windowEnd += n
	d.index = n
}

// Try to find a match starting at index whose length is greater than prevSize.
// We only look at chainCount possibilities before giving up.
// pos = d.index, prevHead = d.chainHead-d.hashOffset, prevLength=minMatchLength-1, lookahead
func (d *compressor) findMatch(pos int, prevHead int, prevLength int, lookahead int) (length, offset int, ok bool) {
	minMatchLook := maxMatchLength
	if lookahead < minMatchLook {
		minMatchLook = lookahead
	}

	win := d.window[0 : pos+minMatchLook]

	// We quit when we get a match that's at least nice long
	nice := len(win) - pos
	if d.nice < nice {
		nice = d.nice
	}

	// If we've got a match that's good enough, only look in 1/4 the chain.
	tries := d.chain
	length = prevLength
	if length >= d.good {
		tries >>= 2
	}

	wEnd := win[pos+length]
	wPos := win[pos:]
	minIndex := pos - windowSize

	for i := prevHead; tries > 0; tries-- {
		if wEnd == win[i+length] {
			n := matchLen(win[i:], wPos, minMatchLook)

			if n > length && (n > minMatchLength || pos-i <= 4096) {
				length = n
				offset = pos - i
				ok = true
				if n >= nice {
					// The match is good enough that we don't try to find a better one.
					break
				}
				wEnd = win[pos+n]
			}
		}
		if i == minIndex {
			// hashPrev[i & windowMask] has already been overwritten, so stop now.
			break
		}
		i = int(d.hashPrev[i&windowMask]) - d.hashOffset
		if i < minIndex || i < 0 {
			break
		}
	}
	return
}

// Try to find a match starting at index whose length is greater than prevSize.
// We only look at chainCount possibilities before giving up.
// pos = d.index, prevHead = d.chainHead-d.hashOffset, prevLength=minMatchLength-1, lookahead
func (d *compressor) findMatchSSE(pos int, prevHead int, prevLength int, lookahead int) (length, offset int, ok bool) {
	minMatchLook := maxMatchLength
	if lookahead < minMatchLook {
		minMatchLook = lookahead
	}

	win := d.window[0 : pos+minMatchLook]

	// We quit when we get a match that's at least nice long
	nice := len(win) - pos
	if d.nice < nice {
		nice = d.nice
	}

	// If we've got a match that's good enough, only look in 1/4 the chain.
	tries := d.chain
	length = prevLength
	if length >= d.good {
		tries >>= 2
	}

	wEnd := win[pos+length]
	wPos := win[pos:]
	minIndex := pos - windowSize

	for i := prevHead; tries > 0; tries-- {
		if wEnd == win[i+length] {
			n := matchLenSSE4(win[i:], wPos, minMatchLook)

			if n > length && (n > minMatchLength || pos-i <= 4096) {
				length = n
				offset = pos - i
				ok = true
				if n >= nice {
					// The match is good enough that we don't try to find a better one.
					break
				}
				wEnd = win[pos+n]
			}
		}
		if i == minIndex {
			// hashPrev[i & windowMask] has already been overwritten, so stop now.
			break
		}
		i = int(d.hashPrev[i&windowMask]) - d.hashOffset
		if i < minIndex || i < 0 {
			break
		}
	}
	return
}

func (d *compressor) writeStoredBlock(buf []byte) error {
	if d.w.writeStoredHeader(len(buf), false); d.w.err != nil {
		return d.w.err
	}
	d.w.writeBytes(buf)
	return d.w.err
}

// oldHash is the hash function used when no native crc32 calculation
// or similar is present.
func oldHash(b []byte) hash {
	return hash(b[0])<<(hashShift*3) + hash(b[1])<<(hashShift*2) + hash(b[2])<<hashShift + hash(b[3])
}

// oldBulkHash will compute hashes using the same
// algorithm as oldHash
func oldBulkHash(b []byte, dst []hash) {
	if len(b) < minMatchLength {
		return
	}
	h := oldHash(b)
	dst[0] = h
	i := 1
	end := len(b) - minMatchLength + 1
	for ; i < end; i++ {
		h = (h << hashShift) + hash(b[i+3])
		dst[i] = h
	}
}

// matchLen returns the number of matching bytes in a and b
// up to length 'max'. Both slices must be at least 'max'
// bytes in size.
func matchLen(a, b []byte, max int) int {
	a = a[:max]
	for i, av := range a {
		if b[i] != av {
			return i
		}
	}
	return max
}

func (d *compressor) initDeflate() {
	d.hashHead = make([]hashid, hashSize)
	d.hashPrev = make([]hashid, windowSize)
	d.window = make([]byte, 2*windowSize)
	d.hashOffset = 1
	d.tokens.tokens = make([]token, maxFlateBlockTokens+1)
	d.length = minMatchLength - 1
	d.offset = 0
	d.byteAvailable = false
	d.index = 0
	d.hash = 0
	d.chainHead = -1
	d.bulkHasher = oldBulkHash
	if useSSE42 {
		d.bulkHasher = crc32sseAll
	}
}

// Assumes that d.fastSkipHashing != skipNever,
// otherwise use deflateLazy
func (d *compressor) deflate() {

	// Sanity enables additional runtime tests.
	// It's intended to be used during development
	// to supplement the currently ad-hoc unit tests.
	const sanity = false

	if d.windowEnd-d.index < minMatchLength+maxMatchLength && !d.sync {
		return
	}

	d.maxInsertIndex = d.windowEnd - (minMatchLength - 1)
	if d.index < d.maxInsertIndex {
		d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
	}

	for {
		if sanity && d.index > d.windowEnd {
			panic("index > windowEnd")
		}
		lookahead := d.windowEnd - d.index
		if lookahead < minMatchLength+maxMatchLength {
			if !d.sync {
				return
			}
			if sanity && d.index > d.windowEnd {
				panic("index > windowEnd")
			}
			if lookahead == 0 {
				if d.tokens.n > 0 {
					if d.err = d.writeBlockSkip(d.tokens, d.index, false); d.err != nil {
						return
					}
					d.tokens.n = 0
				}
				return
			}
		}
		if d.index < d.maxInsertIndex {
			// Update the hash
			d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
			ch := d.hashHead[d.hash]
			d.chainHead = int(ch)
			d.hashPrev[d.index&windowMask] = ch
			d.hashHead[d.hash] = hashid(d.index + d.hashOffset)
		}
		d.length = minMatchLength - 1
		d.offset = 0
		minIndex := d.index - windowSize
		if minIndex < 0 {
			minIndex = 0
		}

		if d.chainHead-d.hashOffset >= minIndex && lookahead > minMatchLength-1 {
			if newLength, newOffset, ok := d.findMatch(d.index, d.chainHead-d.hashOffset, minMatchLength-1, lookahead); ok {
				d.length = newLength
				d.offset = newOffset
			}
		}
		if d.length >= minMatchLength {
			d.ii = 0
			// There was a match at the previous step, and the current match is
			// not better. Output the previous match.
			// "d.length-3" should NOT be "d.length-minMatchLength", since the format always assume 3
			d.tokens.tokens[d.tokens.n] = matchToken(uint32(d.length-3), uint32(d.offset-minOffsetSize))
			d.tokens.n++
			// Insert in the hash table all strings up to the end of the match.
			// index and index-1 are already inserted. If there is not enough
			// lookahead, the last two strings are not inserted into the hash
			// table.
			if d.length <= d.fastSkipHashing {
				var newIndex int
				newIndex = d.index + d.length
				// Calculate missing hashes
				end := newIndex
				if end > d.maxInsertIndex {
					end = d.maxInsertIndex
				}
				end += minMatchLength - 1
				startindex := d.index + 1
				if startindex > d.maxInsertIndex {
					startindex = d.maxInsertIndex
				}
				tocheck := d.window[startindex:end]
				dstSize := len(tocheck) - minMatchLength + 1
				if dstSize > 0 {
					dst := d.hashMatch[:dstSize]
					oldBulkHash(tocheck, dst)
					var newH hash
					for i, val := range dst {
						di := i + startindex
						newH = val & hashMask
						// Get previous value with the same hash.
						// Our chain should point to the previous value.
						d.hashPrev[di&windowMask] = d.hashHead[newH]
						// Set the head of the hash chain to us.
						d.hashHead[newH] = hashid(di + d.hashOffset)
					}
					d.hash = newH
				}
				d.index = newIndex
			} else {
				// For matches this long, we don't bother inserting each individual
				// item into the table.
				d.index += d.length
				if d.index < d.maxInsertIndex {
					d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
				}
			}
			if d.tokens.n == maxFlateBlockTokens {
				// The block includes the current character
				if d.err = d.writeBlockSkip(d.tokens, d.index, false); d.err != nil {
					return
				}
				d.tokens.n = 0
			}
		} else {
			d.ii++
			end := d.index + int(d.ii>>uint(d.fastSkipHashing)) + 1
			if end > d.windowEnd {
				end = d.windowEnd
			}
			for i := d.index; i < end; i++ {
				d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[i]))
				d.tokens.n++
				if d.tokens.n == maxFlateBlockTokens {
					if d.err = d.writeBlockSkip(d.tokens, i+1, false); d.err != nil {
						return
					}
					d.tokens.n = 0
				}
			}
			d.index = end
		}
	}
}

// deflateLazy is the same as deflate, but with d.fastSkipHashing == skipNever,
// meaning it always has lazy matching on.
func (d *compressor) deflateLazy() {
	// Sanity enables additional runtime tests.
	// It's intended to be used during development
	// to supplement the currently ad-hoc unit tests.
	const sanity = false

	if d.windowEnd-d.index < minMatchLength+maxMatchLength && !d.sync {
		return
	}

	d.maxInsertIndex = d.windowEnd - (minMatchLength - 1)
	if d.index < d.maxInsertIndex {
		d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
	}

	for {
		if sanity && d.index > d.windowEnd {
			panic("index > windowEnd")
		}
		lookahead := d.windowEnd - d.index
		if lookahead < minMatchLength+maxMatchLength {
			if !d.sync {
				return
			}
			if sanity && d.index > d.windowEnd {
				panic("index > windowEnd")
			}
			if lookahead == 0 {
				// Flush current output block if any.
				if d.byteAvailable {
					// There is still one pending token that needs to be flushed
					d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
					d.tokens.n++
					d.byteAvailable = false
				}
				if d.tokens.n > 0 {
					if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
						return
					}
					d.tokens.n = 0
				}
				return
			}
		}
		if d.index < d.maxInsertIndex {
			// Update the hash
			d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
			ch := d.hashHead[d.hash]
			d.chainHead = int(ch)
			d.hashPrev[d.index&windowMask] = ch
			d.hashHead[d.hash] = hashid(d.index + d.hashOffset)
		}
		prevLength := d.length
		prevOffset := d.offset
		d.length = minMatchLength - 1
		d.offset = 0
		minIndex := d.index - windowSize
		if minIndex < 0 {
			minIndex = 0
		}

		if d.chainHead-d.hashOffset >= minIndex && lookahead > prevLength && prevLength < d.lazy {
			if newLength, newOffset, ok := d.findMatch(d.index, d.chainHead-d.hashOffset, minMatchLength-1, lookahead); ok {
				d.length = newLength
				d.offset = newOffset
			}
		}
		if prevLength >= minMatchLength && d.length <= prevLength {
			// There was a match at the previous step, and the current match is
			// not better. Output the previous match.
			d.tokens.tokens[d.tokens.n] = matchToken(uint32(prevLength-3), uint32(prevOffset-minOffsetSize))
			d.tokens.n++

			// Insert in the hash table all strings up to the end of the match.
			// index and index-1 are already inserted. If there is not enough
			// lookahead, the last two strings are not inserted into the hash
			// table.
			var newIndex int
			newIndex = d.index + prevLength - 1
			// Calculate missing hashes
			end := newIndex
			if end > d.maxInsertIndex {
				end = d.maxInsertIndex
			}
			end += minMatchLength - 1
			startindex := d.index + 1
			if startindex > d.maxInsertIndex {
				startindex = d.maxInsertIndex
			}
			tocheck := d.window[startindex:end]
			dstSize := len(tocheck) - minMatchLength + 1
			if dstSize > 0 {
				dst := d.hashMatch[:dstSize]
				oldBulkHash(tocheck, dst)
				var newH hash
				for i, val := range dst {
					di := i + startindex
					newH = val & hashMask
					// Get previous value with the same hash.
					// Our chain should point to the previous value.
					d.hashPrev[di&windowMask] = d.hashHead[newH]
					// Set the head of the hash chain to us.
					d.hashHead[newH] = hashid(di + d.hashOffset)
				}
				d.hash = newH
			}

			d.index = newIndex
			d.byteAvailable = false
			d.length = minMatchLength - 1
			if d.tokens.n == maxFlateBlockTokens {
				// The block includes the current character
				if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
					return
				}
				d.tokens.n = 0
			}
		} else {
			// Reset, if we got a match this run.
			if d.length >= minMatchLength {
				d.ii = 0
			}
			// We have a byte waiting. Emit it.
			if d.byteAvailable {
				d.ii++
				d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
				d.tokens.n++
				if d.tokens.n == maxFlateBlockTokens {
					if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
						return
					}
					d.tokens.n = 0
				}
				d.index++

				// If we have a long run of no matches, skip additional bytes
				// Resets when d.ii overflows after 64KB.
				if d.ii > 31 {
					n := int(d.ii >> 6)
					for j := 0; j < n; j++ {
						if d.index >= d.windowEnd-1 {
							break
						}

						d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
						d.tokens.n++
						if d.tokens.n == maxFlateBlockTokens {
							if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
								return
							}
							d.tokens.n = 0
						}
						d.index++
					}
					// Flush last byte
					d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
					d.tokens.n++
					d.byteAvailable = false
					// d.length = minMatchLength - 1 // not needed, since d.ii is reset above, so it should never be > minMatchLength
					if d.tokens.n == maxFlateBlockTokens {
						if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
							return
						}
						d.tokens.n = 0
					}
				}
			} else {
				d.index++
				d.byteAvailable = true
			}
		}
	}
}

// Assumes that d.fastSkipHashing != skipNever,
// otherwise use deflateLazySSE
func (d *compressor) deflateSSE() {

	// Sanity enables additional runtime tests.
	// It's intended to be used during development
	// to supplement the currently ad-hoc unit tests.
	const sanity = false

	if d.windowEnd-d.index < minMatchLength+maxMatchLength && !d.sync {
		return
	}

	d.maxInsertIndex = d.windowEnd - (minMatchLength - 1)
	if d.index < d.maxInsertIndex {
		d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
	}

	for {
		if sanity && d.index > d.windowEnd {
			panic("index > windowEnd")
		}
		lookahead := d.windowEnd - d.index
		if lookahead < minMatchLength+maxMatchLength {
			if !d.sync {
				return
			}
			if sanity && d.index > d.windowEnd {
				panic("index > windowEnd")
			}
			if lookahead == 0 {
				if d.tokens.n > 0 {
					if d.err = d.writeBlockSkip(d.tokens, d.index, false); d.err != nil {
						return
					}
					d.tokens.n = 0
				}
				return
			}
		}
		if d.index < d.maxInsertIndex {
			// Update the hash
			d.hash = crc32sse(d.window[d.index:d.index+minMatchLength]) & hashMask
			ch := d.hashHead[d.hash]
			d.chainHead = int(ch)
			d.hashPrev[d.index&windowMask] = ch
			d.hashHead[d.hash] = hashid(d.index + d.hashOffset)
		}
		d.length = minMatchLength - 1
		d.offset = 0
		minIndex := d.index - windowSize
		if minIndex < 0 {
			minIndex = 0
		}

		if d.chainHead-d.hashOffset >= minIndex && lookahead > minMatchLength-1 {
			if newLength, newOffset, ok := d.findMatchSSE(d.index, d.chainHead-d.hashOffset, minMatchLength-1, lookahead); ok {
				d.length = newLength
				d.offset = newOffset
			}
		}
		if d.length >= minMatchLength {
			d.ii = 0
			// There was a match at the previous step, and the current match is
			// not better. Output the previous match.
			// "d.length-3" should NOT be "d.length-minMatchLength", since the format always assume 3
			d.tokens.tokens[d.tokens.n] = matchToken(uint32(d.length-3), uint32(d.offset-minOffsetSize))
			d.tokens.n++
			// Insert in the hash table all strings up to the end of the match.
			// index and index-1 are already inserted. If there is not enough
			// lookahead, the last two strings are not inserted into the hash
			// table.
			if d.length <= d.fastSkipHashing {
				var newIndex int
				newIndex = d.index + d.length
				// Calculate missing hashes
				end := newIndex
				if end > d.maxInsertIndex {
					end = d.maxInsertIndex
				}
				end += minMatchLength - 1
				startindex := d.index + 1
				if startindex > d.maxInsertIndex {
					startindex = d.maxInsertIndex
				}
				tocheck := d.window[startindex:end]
				dstSize := len(tocheck) - minMatchLength + 1
				if dstSize > 0 {
					dst := d.hashMatch[:dstSize]

					crc32sseAll(tocheck, dst)
					var newH hash
					for i, val := range dst {
						di := i + startindex
						newH = val & hashMask
						// Get previous value with the same hash.
						// Our chain should point to the previous value.
						d.hashPrev[di&windowMask] = d.hashHead[newH]
						// Set the head of the hash chain to us.
						d.hashHead[newH] = hashid(di + d.hashOffset)
					}
					d.hash = newH
				}
				d.index = newIndex
			} else {
				// For matches this long, we don't bother inserting each individual
				// item into the table.
				d.index += d.length
				if d.index < d.maxInsertIndex {
					d.hash = crc32sse(d.window[d.index:d.index+minMatchLength]) & hashMask
				}
			}
			if d.tokens.n == maxFlateBlockTokens {
				// The block includes the current character
				if d.err = d.writeBlockSkip(d.tokens, d.index, false); d.err != nil {
					return
				}
				d.tokens.n = 0
			}
		} else {
			d.ii++
			end := d.index + int(d.ii>>uint(d.fastSkipHashing)) + 1
			if end > d.windowEnd {
				end = d.windowEnd
			}
			for i := d.index; i < end; i++ {
				d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[i]))
				d.tokens.n++
				if d.tokens.n == maxFlateBlockTokens {
					if d.err = d.writeBlockSkip(d.tokens, i+1, false); d.err != nil {
						return
					}
					d.tokens.n = 0
				}
			}
			d.index = end
		}
	}
}

// deflateLazy is the same as deflate, but with d.fastSkipHashing == skipNever,
// meaning it always has lazy matching on.
func (d *compressor) deflateLazySSE() {
	// Sanity enables additional runtime tests.
	// It's intended to be used during development
	// to supplement the currently ad-hoc unit tests.
	const sanity = false

	if d.windowEnd-d.index < minMatchLength+maxMatchLength && !d.sync {
		return
	}

	d.maxInsertIndex = d.windowEnd - (minMatchLength - 1)
	if d.index < d.maxInsertIndex {
		d.hash = crc32sse(d.window[d.index:d.index+minMatchLength]) & hashMask
	}

	for {
		if sanity && d.index > d.windowEnd {
			panic("index > windowEnd")
		}
		lookahead := d.windowEnd - d.index
		if lookahead < minMatchLength+maxMatchLength {
			if !d.sync {
				return
			}
			if sanity && d.index > d.windowEnd {
				panic("index > windowEnd")
			}
			if lookahead == 0 {
				// Flush current output block if any.
				if d.byteAvailable {
					// There is still one pending token that needs to be flushed
					d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
					d.tokens.n++
					d.byteAvailable = false
				}
				if d.tokens.n > 0 {
					if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
						return
					}
					d.tokens.n = 0
				}
				return
			}
		}
		if d.index < d.maxInsertIndex {
			// Update the hash
			d.hash = crc32sse(d.window[d.index:d.index+minMatchLength]) & hashMask
			ch := d.hashHead[d.hash]
			d.chainHead = int(ch)
			d.hashPrev[d.index&windowMask] = ch
			d.hashHead[d.hash] = hashid(d.index + d.hashOffset)
		}
		prevLength := d.length
		prevOffset := d.offset
		d.length = minMatchLength - 1
		d.offset = 0
		minIndex := d.index - windowSize
		if minIndex < 0 {
			minIndex = 0
		}

		if d.chainHead-d.hashOffset >= minIndex && lookahead > prevLength && prevLength < d.lazy {
			if newLength, newOffset, ok := d.findMatchSSE(d.index, d.chainHead-d.hashOffset, minMatchLength-1, lookahead); ok {
				d.length = newLength
				d.offset = newOffset
			}
		}
		if prevLength >= minMatchLength && d.length <= prevLength {
			// There was a match at the previous step, and the current match is
			// not better. Output the previous match.
			d.tokens.tokens[d.tokens.n] = matchToken(uint32(prevLength-3), uint32(prevOffset-minOffsetSize))
			d.tokens.n++

			// Insert in the hash table all strings up to the end of the match.
			// index and index-1 are already inserted. If there is not enough
			// lookahead, the last two strings are not inserted into the hash
			// table.
			var newIndex int
			newIndex = d.index + prevLength - 1
			// Calculate missing hashes
			end := newIndex
			if end > d.maxInsertIndex {
				end = d.maxInsertIndex
			}
			end += minMatchLength - 1
			startindex := d.index + 1
			if startindex > d.maxInsertIndex {
				startindex = d.maxInsertIndex
			}
			tocheck := d.window[startindex:end]
			dstSize := len(tocheck) - minMatchLength + 1
			if dstSize > 0 {
				dst := d.hashMatch[:dstSize]
				crc32sseAll(tocheck, dst)
				var newH hash
				for i, val := range dst {
					di := i + startindex
					newH = val & hashMask
					// Get previous value with the same hash.
					// Our chain should point to the previous value.
					d.hashPrev[di&windowMask] = d.hashHead[newH]
					// Set the head of the hash chain to us.
					d.hashHead[newH] = hashid(di + d.hashOffset)
				}
				d.hash = newH
			}

			d.index = newIndex
			d.byteAvailable = false
			d.length = minMatchLength - 1
			if d.tokens.n == maxFlateBlockTokens {
				// The block includes the current character
				if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
					return
				}
				d.tokens.n = 0
			}
		} else {
			// Reset, if we got a match this run.
			if d.length >= minMatchLength {
				d.ii = 0
			}
			// We have a byte waiting. Emit it.
			if d.byteAvailable {
				d.ii++
				d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
				d.tokens.n++
				if d.tokens.n == maxFlateBlockTokens {
					if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
						return
					}
					d.tokens.n = 0
				}
				d.index++

				// If we have a long run of no matches, skip additional bytes
				// Resets when d.ii overflows after 64KB.
				if d.ii > 31 {
					n := int(d.ii >> 6)
					for j := 0; j < n; j++ {
						if d.index >= d.windowEnd-1 {
							break
						}

						d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
						d.tokens.n++
						if d.tokens.n == maxFlateBlockTokens {
							if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
								return
							}
							d.tokens.n = 0
						}
						d.index++
					}
					// Flush last byte
					d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
					d.tokens.n++
					d.byteAvailable = false
					// d.length = minMatchLength - 1 // not needed, since d.ii is reset above, so it should never be > minMatchLength
					if d.tokens.n == maxFlateBlockTokens {
						if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
							return
						}
						d.tokens.n = 0
					}
				}
			} else {
				d.index++
				d.byteAvailable = true
			}
		}
	}
}

func (d *compressor) fillStore(b []byte) int {
	n := copy(d.window[d.windowEnd:], b)
	d.windowEnd += n
	return n
}

func (d *compressor) store() {
	if d.windowEnd > 0 {
		d.err = d.writeStoredBlock(d.window[:d.windowEnd])
	}
	d.windowEnd = 0
}

// fillHuff will fill the buffer with data for huffman-only compression.
// The number of bytes copied is returned.
func (d *compressor) fillHuff(b []byte) int {
	n := copy(d.window[d.windowEnd:], b)
	d.windowEnd += n
	return n
}

// storeHuff will compress and store the currently added data,
// if enough has been accumulated or we at the end of the stream.
// Any error that occurred will be in d.err
func (d *compressor) storeHuff() {
	// We only compress if we have maxStoreBlockSize or we are at end-of-stream
	if d.windowEnd < maxStoreBlockSize && !d.sync {
		return
	}
	if d.windowEnd == 0 {
		return
	}
	d.w.writeBlockHuff(false, d.window[:d.windowEnd])
	d.err = d.w.err
	d.windowEnd = 0
}

// storeHuff will compress and store the currently added data,
// if enough has been accumulated or we at the end of the stream.
// Any error that occurred will be in d.err
func (d *compressor) storeSnappy() {
	// We only compress if we have maxStoreBlockSize.
	if d.windowEnd < maxStoreBlockSize {
		if !d.sync {
			return
		}
		// Handle extremely small sizes.
		if d.windowEnd < 128 {
			if d.windowEnd == 0 {
				return
			}
			if d.windowEnd <= 32 {
				d.err = d.writeStoredBlock(d.window[:d.windowEnd])
				d.tokens.n = 0
				d.windowEnd = 0
			} else {
				d.w.writeBlockHuff(false, d.window[:d.windowEnd])
				d.err = d.w.err
			}
			d.tokens.n = 0
			d.windowEnd = 0
			return
		}
	}

	d.snap.Encode(&d.tokens, d.window[:d.windowEnd])
	// If we made zero matches, store the block as is.
	if d.tokens.n == d.windowEnd {
		d.err = d.writeStoredBlock(d.window[:d.windowEnd])
		// If we removed less than 1/16th, huffman compress the block.
	} else if d.tokens.n > d.windowEnd-(d.windowEnd>>4) {
		d.w.writeBlockHuff(false, d.window[:d.windowEnd])
		d.err = d.w.err
	} else {
		d.w.writeBlockDynamic(d.tokens, false, d.window[:d.windowEnd])
		d.err = d.w.err
	}
	d.tokens.n = 0
	d.windowEnd = 0
}

// write will add input byte to the stream.
// Unless an error occurs all bytes will be consumed.
func (d *compressor) write(b []byte) (n int, err error) {
	if d.err != nil {
		return 0, d.err
	}
	n = len(b)
	for len(b) > 0 {
		d.step(d)
		b = b[d.fill(d, b):]
		if d.err != nil {
			return 0, d.err
		}
	}
	return n, d.err
}

func (d *compressor) syncFlush() error {
	d.sync = true
	if d.err != nil {
		return d.err
	}
	d.step(d)
	if d.err == nil {
		d.w.writeStoredHeader(0, false)
		d.w.flush()
		d.err = d.w.err
	}
	d.sync = false
	return d.err
}

func (d *compressor) init(w io.Writer, level int) (err error) {
	d.w = newHuffmanBitWriter(w)

	switch {
	case level == NoCompression:
		d.window = make([]byte, maxStoreBlockSize)
		d.fill = (*compressor).fillStore
		d.step = (*compressor).store
	case level == ConstantCompression:
		d.window = make([]byte, maxStoreBlockSize)
		d.fill = (*compressor).fillHuff
		d.step = (*compressor).storeHuff
	case level >= 1 && level <= 3:
		d.snap = newSnappy(level)
		d.window = make([]byte, maxStoreBlockSize)
		d.fill = (*compressor).fillHuff
		d.step = (*compressor).storeSnappy
		d.tokens.tokens = make([]token, maxStoreBlockSize+1)
	case level == DefaultCompression:
		level = 5
		fallthrough
	case 4 <= level && level <= 9:
		d.compressionLevel = levels[level]
		d.initDeflate()
		d.fill = (*compressor).fillDeflate
		if d.fastSkipHashing == skipNever {
			if useSSE42 {
				d.step = (*compressor).deflateLazySSE
			} else {
				d.step = (*compressor).deflateLazy
			}
		} else {
			if useSSE42 {
				d.step = (*compressor).deflateSSE
			} else {
				d.step = (*compressor).deflate

			}
		}
	default:
		return fmt.Errorf("flate: invalid compression level %d: want value in range [-2, 9]", level)
	}
	return nil
}

// Used for zeroing the hash slice
var hzeroes [256]hashid

// reset the state of the compressor.
func (d *compressor) reset(w io.Writer) {
	d.w.reset(w)
	d.sync = false
	d.err = nil
	// We only need to reset a few things for Snappy.
	if d.snap != nil {
		d.snap.Reset()
		d.windowEnd = 0
		d.tokens.n = 0
		return
	}
	switch d.compressionLevel.chain {
	case 0:
		// level was NoCompression or ConstantCompresssion.
		d.windowEnd = 0
	default:
		d.chainHead = -1
		for s := d.hashHead; len(s) > 0; {
			n := copy(s, hzeroes[:])
			s = s[n:]
		}
		for s := d.hashPrev; len(s) > 0; s = s[len(hzeroes):] {
			copy(s, hzeroes[:])
		}
		d.hashOffset = 1

		d.index, d.windowEnd = 0, 0
		d.blockStart, d.byteAvailable = 0, false

		d.tokens.n = 0
		d.length = minMatchLength - 1
		d.offset = 0
		d.hash = 0
		d.ii = 0
		d.maxInsertIndex = 0
	}
}

func (d *compressor) close() error {
	if d.err != nil {
		return d.err
	}
	d.sync = true
	d.step(d)
	if d.err != nil {
		return d.err
	}
	if d.w.writeStoredHeader(0, true); d.w.err != nil {
		return d.w.err
	}
	d.w.flush()
	return d.w.err
}

// NewWriter returns a new Writer compressing data at the given level.
// Following zlib, levels range from 1 (BestSpeed) to 9 (BestCompression);
// higher levels typically run slower but compress more.
// Level 0 (NoCompression) does not attempt any compression; it only adds the
// necessary DEFLATE framing.
// Level -1 (DefaultCompression) uses the default compression level.
// Level -2 (ConstantCompression) will use Huffman compression only, giving
// a very fast compression for all types of input, but sacrificing considerable
// compression efficiency.
//
// If level is in the range [-2, 9] then the error returned will be nil.
// Otherwise the error returned will be non-nil.
func NewWriter(w io.Writer, level int) (*Writer, error) {
	var dw Writer
	if err := dw.d.init(w, level); err != nil {
		return nil, err
	}
	return &dw, nil
}

// NewWriterDict is like NewWriter but initializes the new
// Writer with a preset dictionary.  The returned Writer behaves
// as if the dictionary had been written to it without producing
// any compressed output.  The compressed data written to w
// can only be decompressed by a Reader initialized with the
// same dictionary.
func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) {
	dw := &dictWriter{w}
	zw, err := NewWriter(dw, level)
	if err != nil {
		return nil, err
	}
	zw.d.fillWindow(dict)
	zw.dict = append(zw.dict, dict...) // duplicate dictionary for Reset method.
	return zw, err
}

type dictWriter struct {
	w io.Writer
}

func (w *dictWriter) Write(b []byte) (n int, err error) {
	return w.w.Write(b)
}

// A Writer takes data written to it and writes the compressed
// form of that data to an underlying writer (see NewWriter).
type Writer struct {
	d    compressor
	dict []byte
}

// Write writes data to w, which will eventually write the
// compressed form of data to its underlying writer.
func (w *Writer) Write(data []byte) (n int, err error) {
	return w.d.write(data)
}

// Flush flushes any pending compressed data to the underlying writer.
// It is useful mainly in compressed network protocols, to ensure that
// a remote reader has enough data to reconstruct a packet.
// Flush does not return until the data has been written.
// If the underlying writer returns an error, Flush returns that error.
//
// In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH.
func (w *Writer) Flush() error {
	// For more about flushing:
	// http://www.bolet.org/~pornin/deflate-flush.html
	return w.d.syncFlush()
}

// Close flushes and closes the writer.
func (w *Writer) Close() error {
	return w.d.close()
}

// Reset discards the writer's state and makes it equivalent to
// the result of NewWriter or NewWriterDict called with dst
// and w's level and dictionary.
func (w *Writer) Reset(dst io.Writer) {
	if dw, ok := w.d.w.w.(*dictWriter); ok {
		// w was created with NewWriterDict
		dw.w = dst
		w.d.reset(dw)
		w.d.fillWindow(w.dict)
	} else {
		// w was created with NewWriter
		w.d.reset(dst)
	}
}

// ResetDict discards the writer's state and makes it equivalent to
// the result of NewWriter or NewWriterDict called with dst
// and w's level, but sets a specific dictionary.
func (w *Writer) ResetDict(dst io.Writer, dict []byte) {
	w.dict = dict
	w.d.reset(dst)
	w.d.fillWindow(w.dict)
}


text:
'use strict';

const graphql = require('graphql'),
  relay = require('graphql-relay');

module.exports = (refs) => ({
  type: refs.UserConnection,
  args: relay.connectionArgs,
  resolve: (parent, args, root) => {
    return relay.connectionFromPromisedArray(
      global.app.get('model__user').getUsers(args),
      args
    );
  }
});

redpajama_set_name: RedPajamaGithub


text:
"""A representation of decompilations."""

from retdec.exceptions import ArchiveGenerationFailedError
from retdec.exceptions import CFGGenerationFailedError
from retdec.exceptions import CGGenerationFailedError
from retdec.exceptions import DecompilationFailedError
from retdec.exceptions import NoSuchCFGError
from retdec.exceptions import OutputNotRequestedError
from retdec.resource import Resource

class DecompilationPhase:
    """Phase of a decompilation.

    :param str name: Name of the phase.
    :param str part: Part into which the phase belongs.
    :param str description: Description of the phase.
    :param int completion: What percentage of the decompilation has been
        completed?
    :param list warnings: A list of warnings that were produced by the
        decompiler in the phase. Each warning is a string.

    `part` may be ``None`` if the phase does not belong to any part.
    """

    def __init__(self, name, part, description, completion, warnings):
        self._name = name
        self._part = part
        self._description = description
        self._completion = completion
        self._warnings = warnings

    @property
    def name(self):
        """Name of the phase (`str`)."""
        return self._name

    @property
    def part(self):
        """Part to which the phase belongs (`str`).

        May be ``None`` if the phase does not belong to any part.
        """
        return self._part

    @property
    def description(self):
        """Description of the phase (`str`)."""
        return self._description

    @property
    def completion(self):
        """Completion (in percentages, ``0-100``)."""
        return self._completion

    @property
    def warnings(self):
        """A list of warnings that were produced by the decompiler in the
        phase.

        Each warning is a string.
        """
        return self._warnings

    def __eq__(self, other):
        return (self.__class__ == other.__class__ and
                self.__dict__ == other.__dict__)

    def __ne__(self, other):
        return not self == other

    def __repr__(self):
        return ('{}(name={!r}, part={!r}, description={!r},'
                ' completion={}, warnings={!r})').format(
            __name__ + '.' + self.__class__.__name__,
            self.name,
            self.part,
            self.description,
            self.completion,
            self.warnings
        )

class Decompilation(Resource):
    """A representation of a decompilation."""

    def get_completion(self):
        """How much of the decompilation has been completed (in percentage)?

        It is an ``int`` between 0 and 100.
        """
        self._update_state_if_needed()
        return self._completion

    def get_phases(self):
        """Obtains and returns the list of phases
        (:class:`~retdec.decompilation.DecompilationPhase`).
        """
        self._update_state_if_needed()
        return self._phases

    def wait_until_finished(self, callback=None,
                            on_failure=DecompilationFailedError):
        """Waits until the decompilation is finished.

        :param callable callback: Function to be called when the status of the
            decompilation is changed or when it finishes.
        :param callable on_failure: What should be done when the decompilation
            fails?

        If `callback` is not ``None``, it is called with the decompilation as
        its argument when the status of the decompilation is changed or when it
        finishes.

        If `on_failure` is ``None``, nothing is done when the decompilation
        fails. Otherwise, it is called with the error message. If the returned
        value is an exception, it is raised.
        """
        # Ensure that we have something callable (do nothing by default).
        callback = callback or (lambda _: None)

        # Currently, the retdec.com API does not support push notifications, so
        # we have to do polling.
        # Track completion changes so we can call the callback when the status
        # changes.
        last_completion = None
        while not self.has_finished():
            if (last_completion is not None and
                    self._completion != last_completion):
                callback(self)
            last_completion = self._completion

            self._wait_until_state_can_be_updated()

        # The decompilation has finished.

        # Call the callback one final time. This has to be done because the
        # decompilation may have immediately finished, without giving us chance
        # to call the callback.
        callback(self)

        if self._failed:
            self._handle_failure(on_failure, self._error)

    def get_hll_code(self):
        """Obtains and returns the decompiled code in the high-level language
        (`str`).
        """
        return self._get_file_contents(
            self._path_to_output_file('hll'),
            is_text_file=True
        )

    def save_hll_code(self, directory=None):
        """Saves the decompiled code in the high-level language to the given
        directory.

        :param str directory: Path to a directory in which the decompiled code
            will be stored.

        :returns: Path to the saved file (`str`).

        If `directory` is ``None``, the current working directory is used.
        """
        return self._get_file_and_save_it(
            self._path_to_output_file('hll'),
            directory
        )

    def get_dsm_code(self):
        """Obtains and returns the disassembled input file in assembly-like
        syntax (`str`).
        """
        return self._get_file_contents(
            self._path_to_output_file('dsm'),
            is_text_file=True
        )

    def save_dsm_code(self, directory=None):
        """Saves the disassembled input file in assembly-like syntax to the
        given directory.

        :param str directory: Path to a directory in which the file will be
            stored.

        :returns: Path to the saved file (`str`).

        If `directory` is ``None``, the current working directory is used.
        """
        return self._get_file_and_save_it(
            self._path_to_output_file('dsm'),
            directory
        )

    def cg_generation_has_finished(self):
        """Checks if the call-graph generation has finished.

        :raises OutputNotRequestedError: When the call graph was not requested
            to be generated.
        """
        self._update_state_if_needed()
        return self._cg_status.finished

    def cg_generation_has_succeeded(self):
        """Checks if the call-graph generation has succeeded.

        :raises OutputNotRequestedError: When the call graph was not requested
            to be generated.
        """
        self._update_state_if_needed()
        return self._cg_status.generated

    def cg_generation_has_failed(self):
        """Checks if the call graph has failed to generate.

        :raises OutputNotRequestedError: When the call graph was not requested
            to be generated.
        """
        self._update_state_if_needed()
        return self._cg_status.failed

    def get_cg_generation_error(self):
        """Returns the reason why the call graph failed to generate.

        :raises OutputNotRequestedError: When the call graph was not requested
            to be generated.

        If the call-graph generation has not failed, it returns ``None``.
        """
        self._update_state_if_needed()
        return self._cg_status.error

    def wait_until_cg_is_generated(
            self, on_failure=CGGenerationFailedError):
        """Waits until the call graph is generated.

        :param callable on_failure: What should be done when the generation
            fails?

        :raises OutputNotRequestedError: When the call graph was not requested
            to be generated.

        If `on_failure` is ``None``, nothing is done when the generation fails.
        Otherwise, it is called with the error message. If the returned value
        is an exception, it is raised.
        """
        # Currently, the retdec.com API does not support push notifications, so
        # we have to do polling.
        while not self.cg_generation_has_finished():
            self._wait_until_state_can_be_updated()

        if self._cg_status.failed:
            self._handle_failure(on_failure, self._cg_status.error)

    def save_cg(self, directory=None):
        """Saves the call graph to the given directory.

        :param str directory: Path to a directory in which the file will be
            stored.

        :returns: Path to the saved file (`str`).

        If `directory` is ``None``, the current working directory is used.
        """
        return self._get_file_and_save_it(
            self._path_to_output_file('cg'),
            directory
        )

    @property
    def funcs_with_cfg(self):
        """A list of names of functions having a control-flow graph.

        The returned list does not depend on the control-flow-graph-generation
        status. It always returns the same function names, disregarding whether
        their control-flow graph has or has not been generated.

        The returned list is ordered by function names.

        :raises OutputNotRequestedError: When control-flow graphs were not
            requested to be generated.
        """
        self._update_state_if_needed()
        return sorted(self._cfg_statuses.keys())

    def cfg_generation_has_finished(self, func):
        """Checks if the generation of a control-flow graph for the given
        function has finished.

        :param str func: Name of the function.

        :raises OutputNotRequestedError: When control-flow graphs were not
            requested to be generated.
        :raises NoSuchCFGError: When there is no control-flow graph for the
            given function.
        """
        self._update_state_if_needed()
        return self._cfg_statuses[func].finished

    def cfg_generation_has_succeeded(self, func):
        """Checks if the generation of a control-flow graph for the given
        function has succeeded.

        :param str func: Name of the function.

        :raises OutputNotRequestedError: When control-flow graphs were not
            requested to be generated.
        :raises NoSuchCFGError: When there is no control-flow graph for the
            given function.
        """
        self._update_state_if_needed()
        return self._cfg_statuses[func].generated

    def cfg_generation_has_failed(self, func):
        """Checks if the generation of a control-flow graph for the given
        function has failed.

        :param str func: Name of the function.

        :raises OutputNotRequestedError: When control-flow graphs were not
            requested to be generated.
        :raises NoSuchCFGError: When there is no control-flow graph for the
            given function.
        """
        self._update_state_if_needed()
        return self._cfg_statuses[func].failed

    def get_cfg_generation_error(self, func):
        """Returns the reason why the control-flow graph for the given function
        failed to generate.

        :param str func: Name of the function.

        :raises OutputNotRequestedError: When control-flow graphs were not
            requested to be generated.
        :raises NoSuchCFGError: When there is no control-flow graph for the
            given function.

        If the control-flow-graph generation has not failed, it returns
        ``None``.
        """
        self._update_state_if_needed()
        return self._cfg_statuses[func].error

    def wait_until_cfg_is_generated(
            self, func, on_failure=CFGGenerationFailedError):
        """Waits until the control-flow graph for the given function is
        generated.

        :param str func: Name of the function.
        :param callable on_failure: What should be done when the generation
            fails?

        :raises OutputNotRequestedError: When control-flow graphs were not
            requested to be generated.
        :raises NoSuchCFGError: When there is no control-flow graph for the
            given function.

        If `on_failure` is ``None``, nothing is done when the generation fails.
        Otherwise, it is called with the error message. If the returned value
        is an exception, it is raised.
        """
        # Currently, the retdec.com API does not support push notifications, so
        # we have to do polling.
        while not self.cfg_generation_has_finished(func):
            self._wait_until_state_can_be_updated()

        if self._cfg_statuses[func].failed:
            self._handle_failure(on_failure, self._cfg_statuses[func].error)

    def save_cfg(self, func, directory=None):
        """Saves the control-flow graph for the given function to the given
        directory.

        :param str func: Name of the function.
        :param str directory: Path to a directory in which the file will be
            stored.

        :returns: Path to the saved file (`str`).

        If `directory` is ``None``, the current working directory is used.
        """
        return self._get_file_and_save_it(
            self._path_to_output_file('cfgs/{}'.format(func)),
            directory
        )

    def archive_generation_has_finished(self):
        """Checks if the archive generation has finished.

        :raises OutputNotRequestedError: When the archive was not requested to
            be generated.
        """
        self._update_state_if_needed()
        return self._archive_status.finished

    def archive_generation_has_succeeded(self):
        """Checks if the archive generation has succeeded.

        :raises OutputNotRequestedError: When the archive was not requested to
            be generated.
        """
        self._update_state_if_needed()
        return self._archive_status.generated

    def archive_generation_has_failed(self):
        """Checks if the archive has failed to generate.

        :raises OutputNotRequestedError: When the archive was not requested to
            be generated.
        """
        self._update_state_if_needed()
        return self._archive_status.failed

    def get_archive_generation_error(self):
        """Returns the reason why the archive failed to generate.

        :raises OutputNotRequestedError: When the archive was not requested to
            be generated.

        If the archive has not failed, it returns ``None``.
        """
        self._update_state_if_needed()
        return self._archive_status.error

    def wait_until_archive_is_generated(
            self, on_failure=ArchiveGenerationFailedError):
        """Waits until the archive containing all outputs from the
        decompilation is generated.

        :param callable on_failure: What should be done when the generation
            fails?

        :raises OutputNotRequestedError: When the archive was not requested to
            be generated.

        If `on_failure` is ``None``, nothing is done when the generation fails.
        Otherwise, it is called with the error message. If the returned value
        is an exception, it is raised.
        """
        # Currently, the retdec.com API does not support push notifications, so
        # we have to do polling.
        while not self.archive_generation_has_finished():
            self._wait_until_state_can_be_updated()

        if self._archive_status.failed:
            self._handle_failure(on_failure, self._archive_status.error)

    def save_archive(self, directory=None):
        """Saves the archive containing all outputs from the decompilation
        to the given directory.

        :param str directory: Path to a directory in which the file will be
            stored.

        :returns: Path to the saved file (`str`).

        If `directory` is ``None``, the current working directory is used.
        """
        return self._get_file_and_save_it(
            self._path_to_output_file('archive'),
            directory
        )

    def save_binary(self, directory=None):
        """Saves the compiled version of the input C file (provided that the
        input was a C file) to the given directory.

        :param str directory: Path to a directory in which the file will be
            stored.

        :returns: Path to the saved file (`str`).

        If `directory` is ``None``, the current working directory is used.
        """
        return self._get_file_and_save_it(
            self._path_to_output_file('binary'),
            directory
        )

    def _update_state(self):
        """Updates the state of the decompilation."""
        status = super()._update_state()
        self._completion = status['completion']
        self._phases = self._phases_from_status(status)
        self._cg_status = self._cg_status_from_status(status)
        self._cfg_statuses = self._cfg_statuses_from_status(status)
        self._archive_status = self._archive_status_from_status(status)
        return status

    def _phases_from_status(self, status):
        """Creates a list of phases from the given status."""
        return [
            DecompilationPhase(
                phase['name'],
                phase['part'],
                phase['description'],
                phase['completion'],
                phase['warnings']
            ) for phase in status['phases']
        ]

    def _cg_status_from_status(self, status):
        """Returns the call-graph generation status from the given status."""
        if 'cg' not in status:
            return _NotRequestedOutputStatus()
        return _OutputGenerationStatus(**status['cg'])

    def _cfg_statuses_from_status(self, status):
        """Returns the control-flow-graph generation statuses from the given
        status.
        """
        if 'cfgs' not in status:
            return _DictRaisingOutputNotRequestedError()

        return _DictRaisingErrorWhenNoSuchCFG({
            func: _OutputGenerationStatus(**status)
            for func, status in status['cfgs'].items()
        })

    def _archive_status_from_status(self, status):
        """Returns the archive generation status from the given status."""
        if 'archive' not in status:
            return _NotRequestedOutputStatus()
        return _OutputGenerationStatus(**status['archive'])

    def _path_to_output_file(self, output_file):
        """Returns a path to the given output file."""
        return '/{}/outputs/{}'.format(self.id, output_file)

    def __repr__(self):
        return '<{} id={!r}>'.format(
            __name__ + '.' + self.__class__.__name__,
            self.id
        )

class _OutputGenerationStatus:
    """A status of output generation.

    :param bool generated: Has the output been generated?
    :param bool failed: Has the generation failed?
    :param str error: Reason why the generation failed.
    """

    def __init__(self, generated, failed, error):
        self._generated = generated
        self._failed = failed
        self._error = error

    @property
    def generated(self):
        """Has the output been generated?"""
        return self._generated

    @property
    def failed(self):
        """Has the generation failed?"""
        return self._failed

    @property
    def error(self):
        """Reason why the generation failed (`str`)."""
        return self._error

    @property
    def finished(self):
        """Has the output generation finished?"""
        return self.generated or self.failed

class _NotRequestedOutputStatus:
    """An output generation status that raises
    :class:`~retdec.exceptions.OutputNotRequestedError` whenever it is queried.
    """

    @property
    def generated(self):
        raise OutputNotRequestedError

    @property
    def failed(self):
        raise OutputNotRequestedError

    @property
    def error(self):
        raise OutputNotRequestedError

    @property
    def finished(self):
        raise OutputNotRequestedError

class _DictRaisingOutputNotRequestedError(dict):
    """A dictionary that raises
    :class:`~retdec.exceptions.OutputNotRequestedError` upon access.
    """

    def keys(self):
        raise OutputNotRequestedError

    def __getitem__(self, key):
        raise OutputNotRequestedError

class _DictRaisingErrorWhenNoSuchCFG(dict):
    """A dictionary that raises :class:`~retdec.exceptions.NoSuchCFGError` when
    a key (i.e. a function) is missing.
    """

    def __missing__(self, func):
        raise NoSuchCFGError(func)


text: var ws = require('ws');


text:
// THIS SOURCE CODE IS SUPPLIED "AS IS" WITHOUT WARRANTY OF ANY KIND, AND ITS AUTHOR AND THE JOURNAL OF MACHINE LEARNING RESEARCH (JMLR) AND JMLR'S PUBLISHERS AND DISTRIBUTORS, DISCLAIM ANY AND ALL WARRANTIES, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND ANY WARRANTIES OR NON INFRINGEMENT. THE USER ASSUMES ALL LIABILITY AND RESPONSIBILITY FOR USE OF THIS SOURCE CODE, AND NEITHER THE AUTHOR NOR JMLR, NOR JMLR'S PUBLISHERS AND DISTRIBUTORS, WILL BE LIABLE FOR DAMAGES OF ANY KIND RESULTING FROM ITS USE. Without lim- iting the generality of the foregoing, neither the author, nor JMLR, nor JMLR's publishers and distributors, warrant that the Source Code will be error-free, will operate without interruption, or will meet the needs of the user.
//
// --------------------------------------------------------------------------
//
// Copyright 2011 Stephen Piccolo
//
// This file is part of ML-Flex.
//
// ML-Flex is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// ML-Flex is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ML-Flex. If not, see <http://www.gnu.org/licenses/>.

package mlflex.parallelization;

import mlflex.core.Settings;
import mlflex.core.Singletons;
import mlflex.helper.FileUtilities;

import java.util.ArrayList;
import java.util.concurrent.Callable;

/** This class encapsulates objects necessary to run tasks in parallel across multiple compute nodes. It contains logic for saving/deleting lock files and for handling errors that may occur. It also contains logic to check whether a status file has been created, which would indicate that this task has already been completed.
 */
public class LockedCallable implements Callable<Object>
{
    public static final String DONE_STATUS = "DONE";

    /** This is the path to the status file that indicates whether this task has been completed previously. */
    public String StatusFilePath;
    /** This is the path to the lock file. */
    private String _lockFilePath;
    /** This is what will be output to log files indicating status. */
    private String _logDescription;
    /** This is the callable that will actually be executed after locking has occurred. */
    private Callable<Object> _callable;

    /** Constructor that accepts the objects that are necessary to support the function of this class. Thisi particular constructor is intended to be used when the task being executed is a simple one that doesn't need a complex status file or lock file. The same value is used for the status file, lock file, and lock description.
     * @param simpleDescription Simple description of the task that will be executed
     * @param callable Object that will be executed when locking is successful
     */
    public LockedCallable(String simpleDescription, Callable<Object> callable)
    {
        this(simpleDescription, new java.io.File(simpleDescription).getName(), callable);
    }

    /** Constructor that accepts the objects that are necessary to support the function of this class.
     * @param statusRelativeFilePath Relative path to the status file that indicates whether this task has been completed previously
     * @param logDescription Name fo the task being executed that will be output to the log files
     * @param callable Object that will be executed when locking is successful
     */
    public LockedCallable(String statusRelativeFilePath, String logDescription, Callable<Object> callable)
    {
        StatusFilePath = Settings.STATUS_DIR + statusRelativeFilePath.replace(" ", "_");
        _lockFilePath = Settings.LOCKS_DIR + statusRelativeFilePath.replace(" ", "_");
        _logDescription = logDescription;
        _callable = callable;
    }

    /** This is a convenience method that accepts an array of LockedCallable objects and converts it into a list.
     *
     * @param callables Array of callable arguments
     * @return A List of callable objects
     */
    public static ArrayList<LockedCallable> CreateLockedCallableList(LockedCallable... callables)
    {
        ArrayList<LockedCallable> callableList = new ArrayList<LockedCallable>();
        for (LockedCallable callable : callables)
            callableList.add(callable);

        return callableList;
    }

    /** This method attempts to create a lock file that will indicate to other threads or compute nodes that the _callable task is being executed. If the file cannot be created (most likely because the task is already being executed by another thread/node, then nothing will happen.
     *
     * @return Result of callable
     * @throws Exception
     */
    public Object call() throws Exception
    {
        // If this task has already been completed, then indicate success
        if (FileUtilities.FileExists(StatusFilePath))
        {
            Singletons.Log.Debug("Status file exists at " + StatusFilePath);

            // See if the task is indicated as already being completed
            if (ReadStatus().equals(DONE_STATUS))
            {
                Singletons.Log.Debug("Status is " + DONE_STATUS + " for " + StatusFilePath);
                return Boolean.TRUE;
            }
            else
            {
                Singletons.Log.Debug("Status is PENDING for " + StatusFilePath);

                // See if the status file is stale
                if (FileUtilities.GetFileAgeMinutes(StatusFilePath) > (double)Settings.THREAD_TIMEOUT_MINUTES)
                {
                    Singletons.Log.Debug("PENDING status file is stale at " + StatusFilePath + ", so attempting to delete it");

                    // Delete the status file if it is stale
                    if (FileUtilities.DeleteFile(StatusFilePath))
                        Singletons.Log.Debug("Stale PENDING status file at " + StatusFilePath + " was deleted");
                    else
                        Singletons.Log.Debug("Stale PENDING status file at " + StatusFilePath + " could not be deleted");

                    return Boolean.FALSE;
                }

                return Boolean.FALSE;
            }
        }

        Singletons.Log.Debug("No status file exists at " + StatusFilePath);

        if (!ShouldCreateLockFile()) // Guard clause, indicating whether lock file should be created
            return Boolean.FALSE;

        // Attempting to create a lock file
        if (FileUtilities.CreateEmptyFile(_lockFilePath))
        {
            Singletons.Log.Debug("Lock file was created at " + _lockFilePath);

            try
            {
                Singletons.Log.Debug("Attempting to create PENDING status file at " + StatusFilePath);
                if (FileUtilities.CreateEmptyFile(StatusFilePath))
                {
                    Singletons.Log.Debug("Created PENDING status file at " + StatusFilePath);
                }
                else
                {
                    Singletons.Log.Debug("PENDING status could not be set because file already exists at " + StatusFilePath);
                    DeleteActiveLockFile();
                    return Boolean.FALSE;
                }
            }
            catch (Exception ex)
            {
                Singletons.Log.Debug("Exception occurred when attempting to set PENDING status on file at " + StatusFilePath);
                Singletons.Log.Debug(ex);
                DeleteActiveLockFile();
                return Boolean.FALSE;
            }

            try
            {
               Singletons.Log.Info("Attempt: " + _logDescription);

                // Try to invoke the command
                if (_callable.call().equals(Boolean.TRUE))
                {
                    // Try to create a status file indicating the command was successful
                    Singletons.Log.Debug("Attempting to set " + DONE_STATUS + " status on " + StatusFilePath);
                    FileUtilities.AppendTextToFile(StatusFilePath, DONE_STATUS);
                    Singletons.Log.Debug(DONE_STATUS + " status set on " + StatusFilePath);
                    Singletons.Log.Info("Success: " + _logDescription);
                    // Remove the lock file because it is no longer necessary
                    DeleteActiveLockFile();
                    return Boolean.TRUE;
                }
                else
                {
                    // The task was not processed successfully for whatever reason, so need to retry
                    Singletons.Log.Debug("Retry required: " + _logDescription);
                    FileUtilities.DeleteFile(StatusFilePath);
                    DeleteActiveLockFile();
                    DeleteActiveStatusFile();
                    return Boolean.FALSE;
                }
            }
            catch (Exception ex)
            {
                // Remove the lock file and shutdown hook because they are no longer necessary
                Singletons.Log.Debug("Exception occurred: " + _logDescription);
                Singletons.Log.Debug(ex);
                DeleteActiveLockFile();
                DeleteActiveStatusFile();
                throw ex;
            }
        }

        return Boolean.FALSE;
    }

    /** Checks for a status file and reads the status from a file to see what the status is.
     *
     * @return Status value
     * @throws Exception
     */
    public String ReadStatus() throws Exception
    {
        String status = "";

        try
        {
            status = FileUtilities.ReadScalarFromFile(StatusFilePath);
        }
        catch (Exception ex)
        {
            Singletons.Log.Debug("Error reading status file at " + StatusFilePath);
            Singletons.Log.Debug(ex);
        }

        return status;
    }

    /** Indicates whether this task is already completed
     *
     * @return Whether this task is already completed
     * @throws Exception
     */
    public boolean IsDone() throws Exception
    {
        return FileUtilities.FileExists(StatusFilePath) && ReadStatus().equals(LockedCallable.DONE_STATUS);
    }

    /** This method contains the logic to indicate whether a lock file can be created for this task. If so, then it should be processed. This logic is based on whether other threads are processing it and whether existing lock files are stale, etc.
     *
     * @return Whether the task should be executed
     * @throws Exception
     */
    private Boolean ShouldCreateLockFile() throws Exception
    {
        if (!FileUtilities.FileExists(_lockFilePath))
        {
            Singletons.Log.Debug("No lock file was found at " + _lockFilePath);
            return Boolean.TRUE;
        }

        if (FileUtilities.GetFileAgeMinutes(_lockFilePath) <= (double) Settings.THREAD_TIMEOUT_MINUTES) // The lock file is not stale, so another thread is probably actively processing it
        {
            Singletons.Log.Debug("Lock file was found at " + _lockFilePath + " and is not stale.");
            return Boolean.FALSE;
        }

        if (FileUtilities.DeleteFile(_lockFilePath))
        {
            Singletons.Log.Debug("Stale lock file was found at " + _lockFilePath + " and was deleted.");
            return Boolean.TRUE; // The stale lock file was successfully deleted
        }

        Singletons.Log.Debug("A stale lock file at " + _lockFilePath + " could not be deleted.");
        return Boolean.FALSE; // The lock file is stale but can't be deleted for whatever reason, so delay execution of task
    }

    /** Deletes a lock file that was created by this instance. */
    private void DeleteActiveLockFile()
    {
        Singletons.Log.Debug("Deleting active lock file at " + _lockFilePath);
        FileUtilities.DeleteFile(_lockFilePath);
        Singletons.Log.Debug("Deleted active lock file at " + _lockFilePath);
    }

    /** Deletes a status file that was created by this instance. */
    private void DeleteActiveStatusFile()
    {
        Singletons.Log.Debug("Deleting status file at " + StatusFilePath);
        FileUtilities.DeleteFile(StatusFilePath);
        Singletons.Log.Debug("Deleted status file at " + StatusFilePath);
    }
}


text:
package org.wso2.carbon.transport.http.netty.websocket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wso2.carbon.transport.http.netty.contract.websocket.WebSocketBinaryMessage;
import org.wso2.carbon.transport.http.netty.contract.websocket.WebSocketCloseMessage;
import org.wso2.carbon.transport.http.netty.contract.websocket.WebSocketConnectorListener;
import org.wso2.carbon.transport.http.netty.contract.websocket.WebSocketControlMessage;
import org.wso2.carbon.transport.http.netty.contract.websocket.WebSocketInitMessage;
import org.wso2.carbon.transport.http.netty.contract.websocket.WebSocketTextMessage;

import java.io.IOException;
import javax.websocket.Session;

/**
 * Client connector Listener to check WebSocket pass-through scenarios.
 */
public class WebSocketPassthroughClientConnectorListener implements WebSocketConnectorListener {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketPassthroughClientConnectorListener.class);

    @Override
    public void onMessage(WebSocketInitMessage initMessage) {
        throw new UnsupportedOperationException("Method is not supported");
    }

    @Override
    public void onMessage(WebSocketTextMessage textMessage) {
        try {
            Session serverSession = WebSocketPassThroughTestSessionManager.getInstance().
                    getServerSession(textMessage.getChannelSession());
            serverSession.getBasicRemote().sendText(textMessage.getText());
        } catch (IOException e) {
            logger.error("IO error when sending message: " + e.getMessage());
        }
    }

    @Override
    public void onMessage(WebSocketBinaryMessage binaryMessage) {
        try {
            Session serverSession = WebSocketPassThroughTestSessionManager.getInstance().
                    getServerSession(binaryMessage.getChannelSession());
            serverSession.getBasicRemote().sendBinary(binaryMessage.getByteBuffer());
        } catch (IOException e) {
            logger.error("IO error when sending message: " + e.getMessage());
        }
    }

    @Override
    public void onMessage(WebSocketControlMessage controlMessage) {
        throw new UnsupportedOperationException("Method is not supported");
    }

    @Override
    public void onMessage(WebSocketCloseMessage closeMessage) {
        throw new UnsupportedOperationException("Method is not supported");
    }

    @Override
    public void onError(Throwable throwable) {
    }

    @Override
    public void onIdleTimeout(WebSocketControlMessage controlMessage) {
    }
}


text:
[Tuturials] (https://github.com/PacificBiosciences/Bioinformatics-Training/wiki)

## Instructions to do the SMRT Analysis in a virtualbox can be found:
[link] (https://github.com/PacificBiosciences/Bioinformatics-Training/wiki/SMRT-Analysis-Virtual-Machine-Install)

You will need to install Virtualbox and vagrant (not the one build-in ubuntu one)

Create a new folder called SMRT

In that folder:

```wget https://gist.githubusercontent.com/mjhsieh/701716a527a7966d26ad/raw/92bed57ca054323d0be525eaedbd0749082b8404/Vagrantfile```

Edit the Vagrantfile to share the data folder with the host machine:

add `"config.vm.synced_folder "/data/PacBio_data", "/vagrant/vagrant_data"` in the do |config| part of the file. It will create a folder called vagrant_data in the VM containing the data from /data/PacBio_data.

Adapt cores and memory in Vagrantfile:
--cpus 12 and --memory 32000

If you want to update your VM without having to do `vagrant up`, you can do `vagrant provision`.

###To launch SMRT virtualbox (this might take a long time to launch!)

`cd /data/tools/SMRT`

`vagrant up` if it is the first time
`vagrant reload` if you made changes to the Vagrantfile

N.B: if `vagrant up` gives you the following error: *Vagrant cannot forward the specified ports on this VM*. This is due to a conflict with the build-in Galaxy server in Bio-Linux. In this case, you will have to replace port 8080 by another one (e.g. 5432) in the Vagrantfile (5 replacements in the Vagrantfile).

`vagrant box list`

`vagrant ssh` to go into the VM, the prompt should change to: ```vagrant@vagrant-ubuntu-trusty-64:~$```

`exit` to go back to the host machine

###To launch SMRT portal

In the internet browser: `http://localhost:8080` or http://localhost:5432

user: administrator

password: PacBio#1

[video tuturial] (http://www.pacificbiosciences.com/Tutorials/Bacterial_Assembly_Epigenetic_Analysis_HGAP/story.html)

###Run HGAP on lambda to establish a baseline.

Run RS_HGAP_Assembly using the SMRT Cell in $SEYMOUR_HOME/common/test/primary/lambda, and the pre-packaged lambda reference in $SEYMOUR_HOME/common/userdata/references/lambda.

Make sure you set the Estimated Genome size to 40,000 bp and Minimum Seed Read Length to 3500 bp.

Set these parameters by clicking the box with three dots "..." next to the protocol drop-down menu:

            p_preassembler.minLongReadLength = 3500
            p_celeraassembler.genomeSize = 40000

If the lambda job also fails, then there is a problem with the software configuration that must be investigated.

For more troubleshooting:
[RS HGAP Assembly protocol fails in SMRT Portal] (https://github.com/PacificBiosciences/SMRT-Analysis/wiki/RS-HGAP-Assembly-protocol-fails-in-SMRT-Portal)

###Results

Contig sequences can be found in the following file:

`/home/vagrant/userdata/jobs/016/16439/reference/sequence/reference.fasta`

To export from the VM to the host:

`cat /home/vagrant/userdata/jobs/016/016439/reference/sequence/reference.fasta > /vagrant/vagrant_data/B07_reference.fasta`

or

`sudo mv ~/userdata/jobs/016 /vagrant/vagrant_data/` if you want to remove the data from the VM
`cp ~/userdata/jobs/016 /vagrant/vagrant_data/` if you want to keep a copy in the VM

`sudo mv /vagrant/vagrant_data/016 ~/userdata/jobs/` if you want to put the data back into the VM
`tar -cvf 016.tar 016` in /data/PacBio_data folder to compress result folder


text:
OrientDB supports multi-threaded access to the database.  The `OrientDB` is thread safe, the `ODatabase*` and `OrientGraph*` instances are **not** thread-safe.  You must only use one of this instance per thread and only use each instance in one thread at a time.

The `ODocument`, `OrientVertex` and `OrientEdge` classes are also not thread-safe.  So, sharing them across threads can lead to unexpected errors that may prove difficult to recognize.

>For more information, see [Concurrency](../general/Concurrency.md).

|![](../images/warning.png)|Implicit usage of multiple database instances from the same thread is no longer allowed.  Any attempt to manage multiple instances in the same thread must explicitly call the `db.activateOnCurrentThread()` method against the database instance **before** you use it.|

- [Multi-threading with OrientDB](Java-Multi-Threading-Usage.md)
- [Multi Version Concurrency Control](Java-Multi-Threading-Concurrency.md)

## Basic Example Multi-threading

Example of multithread usage:

```java
OrientDB orientDB = new OrientDB("remote:localhost", OrientDBConfig.defaultConfig());

// Spawn two threads that do some job
new Thread(() ->{
   ODatabaseDocument database = orientDB.open("database", "admin", "admin");
   //... Job One
   database.close();
).start();

new Thread(() ->{
   ODatabaseDocument database = orientDB.open("database", "admin", "admin");
   //... Job two
   database.close();
}).start();

```


text:
//
// Copyright (c) 2004-2021 Jaroslaw Kowalski <jaak@jkowalski.net>, Kim Christensen, Julian Verdurmen
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
//   contributors may be used to endorse or promote products derived from this
//   software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//

namespace NLog.Config
{
    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using JetBrains.Annotations;
    using NLog.Internal;
    using NLog.Common;

    /// <summary>
    /// Repository of interfaces used by NLog to allow override for dependency injection
    /// </summary>
    internal sealed class ServiceRepositoryInternal : ServiceRepository
    {
        private readonly Dictionary<Type, ConfigurationItemCreator> _creatorMap = new Dictionary<Type, ConfigurationItemCreator>();
        private readonly Dictionary<Type, CompiledConstructor> _lateBoundMap = new Dictionary<Type, CompiledConstructor>();
        private readonly object _lockObject = new object();
        public event EventHandler<ServiceRepositoryUpdateEventArgs> TypeRegistered;

        /// <summary>
        /// Initializes a new instance of the <see cref="ServiceRepositoryInternal"/> class.
        /// </summary>
        internal ServiceRepositoryInternal(bool resetGlobalCache = false)
        {
            if (resetGlobalCache)
                ConfigurationItemFactory.Default = null;    //build new global factory

            this.RegisterDefaults();
            // Maybe also include active TimeSource ? Could also be done with LogFactory extension-methods
        }

        public override void RegisterService(Type type, object instance)
        {
            if (type is null)
                throw new ArgumentNullException(nameof(type));
            if (instance is null)
                throw new ArgumentNullException(nameof(instance));

            lock (_lockObject)
            {
                _creatorMap[type] = new ConfigurationItemCreator(t => instance);
            }

            TypeRegistered?.Invoke(this, new ServiceRepositoryUpdateEventArgs(type));
        }

        public override object GetService(Type serviceType)
        {
            var serviceInstance = DefaultResolveInstance(serviceType, null);
            if (serviceInstance is null && serviceType.IsAbstract())
            {
                throw new NLogDependencyResolveException("Instance of class must be registered", serviceType);
            }
            return serviceInstance;
        }

        internal override bool TryGetService<T>(out T serviceInstance)
        {
            serviceInstance = DefaultResolveInstance(typeof(T), null) as T;
            return !(serviceInstance is null);
        }

        private object DefaultResolveInstance(Type itemType, HashSet<Type> seenTypes)
        {
            if (itemType is null)
                throw new ArgumentNullException(nameof(itemType));

            ConfigurationItemCreator objectResolver = null;
            CompiledConstructor compiledConstructor = null;

            lock (_lockObject)
            {
                if (!_creatorMap.TryGetValue(itemType, out objectResolver))
                {
                    _lateBoundMap.TryGetValue(itemType, out compiledConstructor);
                }
            }

            if (objectResolver is null && compiledConstructor is null)
            {
                if (itemType.IsAbstract())
                {
                    if (seenTypes is null)
                        return null;
                    else
                        throw new NLogDependencyResolveException("Instance of class must be registered", itemType);
                }

                // Do not hold lock while resolving types to avoid deadlock on initialization of type static members
                var newCompiledConstructor = CreateCompiledConstructor(itemType);

                lock (_lockObject)
                {
                    if (!_lateBoundMap.TryGetValue(itemType, out compiledConstructor))
                    {
                        _lateBoundMap.Add(itemType, newCompiledConstructor);
                        compiledConstructor = newCompiledConstructor;
                    }
                }
            }

            // Do not hold lock while calling constructor (or resolving parameter values) to avoid deadlock
            var constructorParameters = compiledConstructor?.Parameters;
            if (constructorParameters is null)
            {
                return objectResolver?.Invoke(itemType) ?? compiledConstructor?.Ctor(null);
            }
            else
            {
                seenTypes = seenTypes ?? new HashSet<Type>();
                var parameterValues = CreateCtorParameterValues(constructorParameters, seenTypes);
                return compiledConstructor?.Ctor(parameterValues);
            }
        }

        private CompiledConstructor CreateCompiledConstructor(Type itemType)
        {
            try
            {
                var defaultConstructor = itemType.GetConstructor(Type.EmptyTypes);
                if (defaultConstructor is null)
                {
                    InternalLogger.Trace("Resolves parameterized constructor for {0}", itemType);
                    var ctor = GetParameterizedConstructor(itemType);
                    var constructorMethod = ReflectionHelpers.CreateLateBoundConstructor(ctor);
                    return new CompiledConstructor(constructorMethod, ctor.GetParameters());
                }
                else
                {
                    InternalLogger.Trace("Resolves default constructor for {0}", itemType);
                    var constructorMethod = ReflectionHelpers.CreateLateBoundConstructor(defaultConstructor);
                    return new CompiledConstructor(constructorMethod);
                }
            }
            catch (MissingMethodException exception)
            {
                throw new NLogDependencyResolveException("Is the required permission granted?", exception, itemType);
            }
            finally
            {
                InternalLogger.Trace("Resolve {0} done", itemType.FullName);
            }
        }

        private static ConstructorInfo GetParameterizedConstructor(Type itemType)
        {
            var ctors = itemType.GetConstructors();

            if (ctors.Length == 0)
            {
                throw new NLogDependencyResolveException("No public constructor", itemType);
            }

            if (ctors.Length > 1)
            {
                throw new NLogDependencyResolveException("Multiple public constructor are not supported if there isn't a default constructor'", itemType);
            }

            var ctor = ctors[0];
            return ctor;
        }

        private object[] CreateCtorParameterValues(ParameterInfo[] parameterInfos, HashSet<Type> seenTypes)
        {
            var parameterValues = new object[parameterInfos.Length];

            for (var i = 0; i < parameterInfos.Length; i++)
            {
                var param = parameterInfos[i];

                var parameterType = param.ParameterType;
                if (seenTypes.Contains(parameterType))
                {
                    throw new NLogDependencyResolveException("There is a cycle", parameterType);
                }

                seenTypes.Add(parameterType);

                var paramValue = DefaultResolveInstance(parameterType, seenTypes);
                parameterValues[i] = paramValue;
            }

            return parameterValues;
        }

        private sealed class CompiledConstructor
        {
            [NotNull] public ReflectionHelpers.LateBoundConstructor Ctor { get; }
            [CanBeNull] public ParameterInfo[] Parameters { get; }

            public CompiledConstructor([NotNull] ReflectionHelpers.LateBoundConstructor ctor, ParameterInfo[] parameters = null)
            {
                Ctor = ctor ?? throw new ArgumentNullException(nameof(ctor));
                Parameters = parameters;
            }
        }
    }
}


text:
@interface PKAssembly ()
- (id)peek;
- (NSString *)consumedObjectsJoinedByString:(NSString *)delimiter;
@end

@interface PKParser ()
- (NSSet *)matchAndAssemble:(NSSet *)inAssemblies;
- (PKAssembly *)best:(NSSet *)inAssemblies;
@end

@interface PKTrack ()
- (void)throwTrackExceptionWithPreviousState:(NSSet *)inAssemblies parser:(PKParser *)p;
@end

@interface PKCollectionParser ()
+ (PKCollectionParser *)collectionParserWithFirst:(PKParser *)p1 rest:(va_list)rest;
@end

@implementation PKTrack

+ (PKTrack *)track {
    return [self trackWithSubparsers:nil];
}

+ (PKTrack *)trackWithSubparsers:(PKParser *)p1, ... {
    va_list vargs;
    va_start(vargs, p1);
    PKTrack *tr = (PKTrack *)[self collectionParserWithFirst:p1 rest:vargs];
    va_end(vargs);
    return tr;
}

- (NSSet *)allMatchesFor:(NSSet *)inAssemblies {
    NSParameterAssert(inAssemblies);
    BOOL inTrack = NO;
    NSSet *lastAssemblies = inAssemblies;
    NSSet *outAssemblies = inAssemblies;

    for (PKParser *p in subparsers) {
        outAssemblies = [p matchAndAssemble:outAssemblies];
        if (![outAssemblies count]) {
            if (inTrack) {
                [self throwTrackExceptionWithPreviousState:lastAssemblies parser:p];
            }
            break;
        }
        inTrack = YES;
        lastAssemblies = outAssemblies;
    }

    return outAssemblies;
}

- (void)throwTrackExceptionWithPreviousState:(NSSet *)inAssemblies parser:(PKParser *)p {
    PKAssembly *best = [self best:inAssemblies];

    NSString *after = [best consumedObjectsJoinedByString:@" "];
    if (![after length]) {
        after = @"-nothing-";
    }

    NSString *expected = [p description];

    id next = [best peek];
    NSString *found = next ? [next description] : @"-nothing-";

    NSString *reason = [NSString stringWithFormat:@"\n\nAfter : %@\nExpected : %@\nFound : %@\n\n", after, expected, found];
    NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
                              after, @"after",
                              expected, @"expected",
                              found, @"found",
                              nil];
    [[PKTrackException exceptionWithName:PKTrackExceptionName reason:reason userInfo:userInfo] raise];
}

@end


text:
'use strict';

Object.defineProperty(exports, '__esModule', {
  value: true
});

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var _refsStack = require('./refs-stack');

var _refsStack2 = _interopRequireDefault(_refsStack);

// Instances of this class interface with an [extension mechanism](https://github.com/Matt-Esch/virtual-dom/blob/master/docs/hooks.md)
// in the `virtual-dom` library called "hooks". When virtual nodes have
// properties that reference hook instances, `virtual-dom` will call `hook`
// and `unhook` on this object with the underlying DOM node when it is created
// and destroyed.
//
// We maintain a global stack of simple `Object` instances in which to store
// references. When creating or updating a component, we push its associated
// `refs` object to the top of the stack. This allows the hooks to assign
// references into the component whose element we are currently creating or
// updating.

var RefHook = (function () {
  function RefHook(refName) {
    _classCallCheck(this, RefHook);

    this.refName = refName;
  }

  _createClass(RefHook, [{
    key: 'hook',
    value: function hook(node) {
      _refsStack2['default'][_refsStack2['default'].length - 1][this.refName] = node;
    }
  }, {
    key: 'unhook',
    value: function unhook(node) {
      var currentRefs = _refsStack2['default'][_refsStack2['default'].length - 1];
      if (_refsStack2['default'].length > 0 && currentRefs[this.refName] === node) {
        delete currentRefs[this.refName];
      }
    }
  }]);

  return RefHook;
})();

exports['default'] = RefHook;
module.exports = exports['default'];


text:
localIcons=('AnalyticsApp' 'Beaker' 'BrowseTable' 'CalendarDay' 'CalendarHour' 'CalendarMonth' 'CalendarQuarter' 'CalendarWeek' 'ChartArea' 'ChartBar' 'ChartBoxPlot' 'ChartTimeline' 'CheckProgress' 'CollapseAll' 'ColorFill' 'ColorText' 'CrossFilter' 'DashboardFile' 'DashboardGauge' 'DigitalMarketingApp' 'DimensionFill' 'DocumentFile' 'Download' 'ExpandCollapse' 'Explore' 'FieldString' 'FieldTier' 'FindSelected' 'Flag' 'GitBranch' 'IdeDimension' 'IdeDimensionGroup' 'IdeFileDashboard' 'IdeFileDocument' 'IdeFileGeneric' 'IdeFileLookMl' 'IdeFileManifest' 'IdeFileModel' 'IdeParameter' 'LogoRings' 'LookerLogo' 'Lqa' 'Marketplace' 'ModelFile' 'More' 'Notes' 'Pivot' 'Public' 'QuickStart' 'Reports' 'Return' 'SalesAnalytics' 'SendWebhook' 'SqlRunner' 'UserAttributes' 'ViewFile' 'VisArea' 'VisBar' 'VisColumn' 'VisLine' 'VisMap' 'VisPie' 'VisScatter' 'VisSinglueValue' 'VisTable')

for icon in ${localIcons[@]}; do
  echo "Update $icon to <$icon /> from @looker/icons"
  find . -type f -name "*.tsx" -print0 | xargs -0 sed -i -e "s/icon=\"$icon\"/icon={<$icon \/>}/g"
  find . -type f -name "*.tsx" -print0 | xargs -0 sed -i -e "s/name=\"$icon\"/icon={<$icon \/>}/g"
  find . -type f -name "*.tsx" -print0 | xargs -0 sed -i -e "s/iconBefore=\"$icon\"/iconBefore={<$icon \/>}/g"
  find . -type f -name "*.tsx" -print0 | xargs -0 sed -i -e "s/iconAfter=\"$icon\"/iconAfter={<$icon \/>}/g"
done

icons='Account account_circle
AddAlerts add_alert
AddComment add_comment
AlignCenter format_align_center
AlignLeft format_align_left
AlignRight format_align_right
API device_hub
ApplicationSelect apps
ArrowBackward arrow_back
ArrowDownward arrow_downward
ArrowDropDown arrow_drop_down
ArrowDropUp arrow_drop_up
ArrowForward arrow_forward
ArrowLeft arrow_left
ArrowRight arrow_right
ArrowUpward arrow_upward
Block block
Board assignment
CacheRefresh cached
Calendar date_range
CenterFocus center_focus_weak
CaretDown expand_more
CaretLeft chevron_left
CaretRight chevron_right
CaretUp expand_less
ChangeHistory change_history
ChartColumn bar_chart
ChartCustom multiline_chart
ChartDonutMultiples donut_large
ChartFunnel filter_list
ChartLine show_chart
ChartMap map
ChartPie pie_chart
ChartScatterplot bubble_chart
ChartSingleRecord toc
ChartSingleValue looks_6
ChartTable table_chart
ChartWaterfall waterfall_chart
ChartWordcloud line_style
Chat chat
Check done
CircleAdd add_circle
CircleAddOutline add_circle_outline
CircleCancel cancel
CircleCheck check_circle
CircleExplore explore
CircleInfo info
CircleInfoOutline info
CircleQuestion help
CircleQuestionOutline help
CircleRemove remove_circle
Clipboard assignment
Clock schedule
Close close
Code code
Comment comment
Dashboard dashboard
DNS dns
DotsHorz more_horiz
DotsVert more_vert
DragHandle drag_handle
DragHandleDots drag_indicator
Edit create
EditOutline create
ExpandMore expand_more
ExploreOutline explore
External launch
Error error
ErrorOutline error
FactCheck fact_check
Favorite favorite
FavoriteOutline favorite
Feedback feedback
FeedbackOutline feedback
FieldDate calendar_today
FieldDuration hourglass_empty
FieldLocation place
FieldNumber tag
FieldYesNo check
File note
FileBlank insert_drive_file
Filter filter_list
Folder folder
FolderClosed folder
FolderMove drive_file_move
FolderNew create_new_folder
FolderOpen folder_open
FolderShared folder_shared
FormatBold format_bold
FormatItalic format_italic
FormatListBullet format_list_bulleted
FormatListNumbered format_list_numbered
FormatQuote format_list_numbered
FormatTitle title
FormatUnderlined format_underlined
Functions functions
Gear settings
GearOutline settings
Group group
Hamburger menu
Help live_help
Home home
IdeFileStrings language
IdeFileView table_chart
Image insert_photo
Key vpn_key
Link link
LockClosed lock
Logout logout
Mail email
Minus remove
MultiSelect library_add_check
Note insert_drive_file
NoteOutline insert_drive_file
NotificationBellOff notifications
NotificationBellOn notifications_active
Pin push_pin
Plus add
Popular trending_up
Projects business_center
RecentActivity history
Redo redo
Refresh refresh
ScheduleOutline send
Search search
SectionDrop branding_watermark
SendEmail email
SendSftp drive_file_move
Share share
ShareAlt ios_share
SortAlpha sort_by_alpha
Space assignment
Style style
Sync sync_alt
Table table_chart
TextFormat text_format
TimeZone language
Trash delete
TrashOutline delete
Tune tune
Undo undo
UnusedContent low_priority
Update update
User person_outline
Validate verified_user
ViewColumn view_column
ViewGrid grid_view
Visibility visibility
VisibilityOff visibility_off
VisibilityOutline visibility
Visualization assessment
Warning warning
WarningOutline warning'

IFS=$'\n' iconSet=($icons)

for icon in ${iconSet[@]}; do
  IFS=' ' read -ra iconParts <<< "$icon"
  old=(${iconParts[0]})
  new=$(echo ${iconParts[1]} | sed -r 's/(^|_)([a-z])/\U\2/g')

  echo "Move $old to <$new />"
  find . -type f -name "*.tsx" -print0 | xargs -0 sed -i -e "s/icon=\"$old\"/icon={<$new \/>}/g"
  find . -type f -name "*.tsx" -print0 | xargs -0 sed -i -e "s/name=\"$old\"/icon={<$new \/>}/g"
  find . -type f -name "*.tsx" -print0 | xargs -0 sed -i -e "s/iconBefore=\"$old\"/iconBefore={<$new \/>}/g"
  find . -type f -name "*.tsx" -print0 | xargs -0 sed -i -e "s/iconAfter=\"$old\"/iconAfter={<$new \/>}/g"
done