/* Generalized Segment Utilities
-------------------------------------------------------------------------------------------------
175857
function isDaySegmentCollision(segment, otherSegments) {
	for (var i=0; i<otherSegments.length; i++) {
		var otherSegment = otherSegments[i];
		if (
			otherSegment.leftCol <= segment.rightCol &&
			otherSegment.rightCol >= segment.leftCol
		) {
			return true;
		}
	}
	return false;
}
1324838
function getPathSegementToOutput(transform, pathSegment) {
    var rootlessPathSegment = pathSegment
    if(pathSegment[0] === root)
        rootlessPathSegment = pathSegment.slice(1) // slice the root off

    if(transform === undefined) {
        var resultPath = rootlessPathSegment
    } else {
        var resultPath = transform.toExternal(rootlessPathSegment)
    }

    return resultPath
}
1228095
void assignExclusiveSegments(List<MemorySegment> segments) {
		checkState(this.initialCredit == 0, "Bug in input channel setup logic: exclusive buffers have " +
			"already been set for this input channel.");

		checkNotNull(segments);
		checkArgument(segments.size() > 0, "The number of exclusive buffers per channel should be larger than 0.");

		this.initialCredit = segments.size();
		this.numRequiredBuffers = segments.size();

		synchronized (bufferQueue) {
			for (MemorySegment segment : segments) {
				bufferQueue.addExclusiveBuffer(new NetworkBuffer(segment, this), numRequiredBuffers);
			}
		}
	}
831512
function (segment) {

				var ARG_PATTERN = /\((.*?):([a-zA-Z0-9_]*)\)/g;  // (:id)  , ([0-9]+:id) , ([^\/]+:id)
				var INFINITE_PATTERN = /\(\.\.\.\)/g; // (...)
				var INFINITE_STR = '(...)';

				var obj = {
					args: [],
					pattern: segment
				};

				obj.pattern = obj.pattern.replace(INFINITE_PATTERN, function () {
					obj.args.push({
						infinite: true,
						pattern: INFINITE_STR
					});
					return INFINITE_STR;
				});

				obj.pattern = obj.pattern.replace(ARG_PATTERN, function ($0, exp, name) {
					var pattern = '(?P<' + name + '>' + (options.aliases[exp] ? options.aliases[exp] : exp) + ')';
					obj.args.push({
						name: name,
						pattern: pattern
					});
					return pattern;
				});
				return obj;
			}
1145492
function () {							// <<<< public
		var randSegListArray = this.polyData.getSegments().concat();
//		console.log( "Polygon Chains: ", dumpSegmentList( randSegListArray ) );
		PNLTRI.Math.array_shuffle( randSegListArray );
		this.optimise_randomlist( randSegListArray );
//		console.log( "Random Segment Sequence: ", dumpRandomSequence( randSegListArray ) );

		var nbSegs = randSegListArray.length;
		var myQs = this.queryStructure;

		var i, current = 0, logstar = nbSegs;
		while ( current < nbSegs ) {
			// The CENTRAL mechanism for the near-linear performance:
			//	stratefies the loop through all segments into log* parts
			//	and computes new root-Nodes for the remaining segments in each
			//	partition.
			logstar = Math.log(logstar)/Math.LN2;		// == log2(logstar)
			var partEnd = ( logstar > 1 ) ? Math.floor( nbSegs / logstar ) : nbSegs;

			// Core: adds next partition of the segments
			for (; current < partEnd; current++ ) { myQs.add_segment( randSegListArray[current] ); }
//			console.log( nbSegs, current );

			// To speed up the segment insertion into the trapezoidation
			//	the endponts of those segments not yet inserted
			//	are repeatedly pre-located,
			// thus their final location-query can start at the top of the
			//	appropriate sub-tree instead of the root of the whole
			//	query structure.
			//
			for (i = current; i < nbSegs; i++) { this.queryStructure.segNodes( randSegListArray[i] ); }
		}

		myQs.assignDepths( this.polyData );
		// cleanup to support garbage collection
		for (i = 0; i < nbSegs; i++) { randSegListArray[i].trLeft = randSegListArray[i].trRight = null; }
	}
1251402
private void freeCompactedSegments() {
        SegmentManager segManager = _dataArray.getSegmentManager();
        if(segManager == null) return;
        
        while(!_freeQueue.isEmpty()) {
            Segment seg = _freeQueue.remove();
            try {
                segManager.freeSegment(seg);
            } catch(Exception e) {
                _log.error("failed to free Segment " + seg.getSegmentId() + ": " + seg.getStatus(), e);
            }
        }
    }
125834
function(t) {

            var segments = this.segments;
            var numSegments = segments.length;
            if (numSegments === 0) return null; // if segments is an empty array

            var segmentIndex = t.segmentIndex;
            if (segmentIndex < 0) return segments[0].pointAtT(0);
            if (segmentIndex >= numSegments) return segments[numSegments - 1].pointAtT(1);

            var tValue = t.value;
            if (tValue < 0) tValue = 0;
            else if (tValue > 1) tValue = 1;

            return segments[segmentIndex].pointAtT(tValue);
        }
316183
function(arrayBuffer, sliceSize) {
		var segments= [],
			fi = 0;
		while(fi * sliceSize < arrayBuffer.byteLength){
			segments.push(arrayBuffer.slice(fi * sliceSize, (fi + 1) * sliceSize));
			fi++;
		}
		return segments;
	}
1256174
private Segment currentSegment() {
    Segment segment = segments.currentSegment();
    if (segment.isFull()) {
      segments.currentSegment().flush();
      segment = segments.nextSegment();
    }
    return segment;
  }
218727
@Override
	protected MemorySegment nextSegment(MemorySegment current, int positionInCurrent) throws EOFException
	{
		if (++this.currentSegmentIndex < this.segments.length) {
			return this.segments[this.currentSegmentIndex];
		} else {
			throw new EOFException();
		}
	}
941153
private static List<Segment> parseSegments(String origPathStr) {
        String pathStr = origPathStr;
        if (!pathStr.startsWith("/")) {
            pathStr = pathStr + "/";
        }

        List<Segment> result = new ArrayList<>();
        for (String segmentStr : PATH_SPLITTER.split(pathStr)) {
            Matcher m = SEGMENT_PATTERN.matcher(segmentStr);
            if (!m.matches()) {
                throw new IllegalArgumentException("Bad aql path: " + origPathStr);
            }
            Segment segment = new Segment();
            segment.attribute = m.group(1);
            segment.nodeId = m.groupCount() >= 3 ? m.group(3) : null;
            result.add(segment);
        }
        return result;
    }
292045
protected void selectSegment(Segment segment) {
    if(segment.isUnpaired()) {
      // remember selected unpaired segment
      for(Segment other : segments.getPairedSegments(segment)) {
        indirectSelections.put(other, segment);
        selectSegment(other);
      }
    }
    else {
      if(!selectedSegments.contains(segment)) {
        selectedSegments.add(segment);
        if(segment.getDBIDs() != null) {
          unselectedObjects.removeDBIDs(segment.getDBIDs());
        }
      }
    }
  }
155232
function SegmentChainer(segments, eps, buildLog){
	var chains = [];
	var regions = [];

	segments.forEach(function(seg){
		var pt1 = seg.start;
		var pt2 = seg.end;
		if (eps.pointsSame(pt1, pt2)){
			console.warn('PolyBool: Warning: Zero-length segment detected; your epsilon is ' +
				'probably too small or too large');
			return;
		}

		if (buildLog)
			buildLog.chainStart(seg);

		// search for two chains that this segment matches
		var first_match = {
			index: 0,
			matches_head: false,
			matches_pt1: false
		};
		var second_match = {
			index: 0,
			matches_head: false,
			matches_pt1: false
		};
		var next_match = first_match;
		function setMatch(index, matches_head, matches_pt1){
			// return true if we've matched twice
			next_match.index = index;
			next_match.matches_head = matches_head;
			next_match.matches_pt1 = matches_pt1;
			if (next_match === first_match){
				next_match = second_match;
				return false;
			}
			next_match = null;
			return true; // we've matched twice, we're done here
		}
		for (var i = 0; i < chains.length; i++){
			var chain = chains[i];
			var head  = chain[0];
			var head2 = chain[1];
			var tail  = chain[chain.length - 1];
			var tail2 = chain[chain.length - 2];
			if (eps.pointsSame(head, pt1)){
				if (setMatch(i, true, true))
					break;
			}
			else if (eps.pointsSame(head, pt2)){
				if (setMatch(i, true, false))
					break;
			}
			else if (eps.pointsSame(tail, pt1)){
				if (setMatch(i, false, true))
					break;
			}
			else if (eps.pointsSame(tail, pt2)){
				if (setMatch(i, false, false))
					break;
			}
		}

		if (next_match === first_match){
			// we didn't match anything, so create a new chain
			chains.push([ pt1, pt2 ]);
			if (buildLog)
				buildLog.chainNew(pt1, pt2);
			return;
		}

		if (next_match === second_match){
			// we matched a single chain

			if (buildLog)
				buildLog.chainMatch(first_match.index);

			// add the other point to the apporpriate end, and check to see if we've closed the
			// chain into a loop

			var index = first_match.index;
			var pt = first_match.matches_pt1 ? pt2 : pt1; // if we matched pt1, then we add pt2, etc
			var addToHead = first_match.matches_head; // if we matched at head, then add to the head

			var chain = chains[index];
			var grow  = addToHead ? chain[0] : chain[chain.length - 1];
			var grow2 = addToHead ? chain[1] : chain[chain.length - 2];
			var oppo  = addToHead ? chain[chain.length - 1] : chain[0];
			var oppo2 = addToHead ? chain[chain.length - 2] : chain[1];

			if (eps.pointsCollinear(grow2, grow, pt)){
				// grow isn't needed because it's directly between grow2 and pt:
				// grow2 ---grow---> pt
				if (addToHead){
					if (buildLog)
						buildLog.chainRemoveHead(first_match.index, pt);
					chain.shift();
				}
				else{
					if (buildLog)
						buildLog.chainRemoveTail(first_match.index, pt);
					chain.pop();
				}
				grow = grow2; // old grow is gone... new grow is what grow2 was
			}

			if (eps.pointsSame(oppo, pt)){
				// we're closing the loop, so remove chain from chains
				chains.splice(index, 1);

				if (eps.pointsCollinear(oppo2, oppo, grow)){
					// oppo isn't needed because it's directly between oppo2 and grow:
					// oppo2 ---oppo--->grow
					if (addToHead){
						if (buildLog)
							buildLog.chainRemoveTail(first_match.index, grow);
						chain.pop();
					}
					else{
						if (buildLog)
							buildLog.chainRemoveHead(first_match.index, grow);
						chain.shift();
					}
				}

				if (buildLog)
					buildLog.chainClose(first_match.index);

				// we have a closed chain!
				regions.push(chain);
				return;
			}

			// not closing a loop, so just add it to the apporpriate side
			if (addToHead){
				if (buildLog)
					buildLog.chainAddHead(first_match.index, pt);
				chain.unshift(pt);
			}
			else{
				if (buildLog)
					buildLog.chainAddTail(first_match.index, pt);
				chain.push(pt);
			}
			return;
		}

		// otherwise, we matched two chains, so we need to combine those chains together

		function reverseChain(index){
			if (buildLog)
				buildLog.chainReverse(index);
			chains[index].reverse(); // gee, that's easy
		}

		function appendChain(index1, index2){
			// index1 gets index2 appended to it, and index2 is removed
			var chain1 = chains[index1];
			var chain2 = chains[index2];
			var tail  = chain1[chain1.length - 1];
			var tail2 = chain1[chain1.length - 2];
			var head  = chain2[0];
			var head2 = chain2[1];

			if (eps.pointsCollinear(tail2, tail, head)){
				// tail isn't needed because it's directly between tail2 and head
				// tail2 ---tail---> head
				if (buildLog)
					buildLog.chainRemoveTail(index1, tail);
				chain1.pop();
				tail = tail2; // old tail is gone... new tail is what tail2 was
			}

			if (eps.pointsCollinear(tail, head, head2)){
				// head isn't needed because it's directly between tail and head2
				// tail ---head---> head2
				if (buildLog)
					buildLog.chainRemoveHead(index2, head);
				chain2.shift();
			}

			if (buildLog)
				buildLog.chainJoin(index1, index2);
			chains[index1] = chain1.concat(chain2);
			chains.splice(index2, 1);
		}

		var F = first_match.index;
		var S = second_match.index;

		if (buildLog)
			buildLog.chainConnect(F, S);

		var reverseF = chains[F].length < chains[S].length; // reverse the shorter chain, if needed
		if (first_match.matches_head){
			if (second_match.matches_head){
				if (reverseF){
					// <<<< F <<<< --- >>>> S >>>>
					reverseChain(F);
					// >>>> F >>>> --- >>>> S >>>>
					appendChain(F, S);
				}
				else{
					// <<<< F <<<< --- >>>> S >>>>
					reverseChain(S);
					// <<<< F <<<< --- <<<< S <<<<   logically same as:
					// >>>> S >>>> --- >>>> F >>>>
					appendChain(S, F);
				}
			}
			else{
				// <<<< F <<<< --- <<<< S <<<<   logically same as:
				// >>>> S >>>> --- >>>> F >>>>
				appendChain(S, F);
			}
		}
		else{
			if (second_match.matches_head){
				// >>>> F >>>> --- >>>> S >>>>
				appendChain(F, S);
			}
			else{
				if (reverseF){
					// >>>> F >>>> --- <<<< S <<<<
					reverseChain(F);
					// <<<< F <<<< --- <<<< S <<<<   logically same as:
					// >>>> S >>>> --- >>>> F >>>>
					appendChain(S, F);
				}
				else{
					// >>>> F >>>> --- <<<< S <<<<
					reverseChain(S);
					// >>>> F >>>> --- >>>> S >>>>
					appendChain(F, S);
				}
			}
		}
	});

	return regions;
}
29843
function(t, opt) {

            var segments = this.segments;
            var numSegments = segments.length;
            if (numSegments === 0) return 0; // if segments is an empty array

            var segmentIndex = t.segmentIndex;
            if (segmentIndex < 0) return 0; // regardless of t.value

            var tValue = t.value;
            if (segmentIndex >= numSegments) {
                segmentIndex = numSegments - 1;
                tValue = 1;
            }
            else if (tValue < 0) tValue = 0;
            else if (tValue > 1) tValue = 1;

            opt = opt || {};
            var precision = (opt.precision === undefined) ? this.PRECISION : opt.precision;
            var segmentSubdivisions = (opt.segmentSubdivisions === undefined) ? this.getSegmentSubdivisions({ precision: precision }) : opt.segmentSubdivisions;
            // not using localOpt

            var subdivisions;
            var length = 0;
            for (var i = 0; i < segmentIndex; i++) {

                var segment = segments[i];
                subdivisions = segmentSubdivisions[i];
                length += segment.length({ precisison: precision, subdivisions: subdivisions });
            }

            segment = segments[segmentIndex];
            subdivisions = segmentSubdivisions[segmentIndex];
            length += segment.lengthAtT(tValue, { precisison: precision, subdivisions: subdivisions });

            return length;
        }
744102
function(p) {

            if (!p) return false;

            var segments = this.segments;
            var otherSegments = p.segments;

            var numSegments = segments.length;
            if (otherSegments.length !== numSegments) return false; // if the two paths have different number of segments, they cannot be equal

            for (var i = 0; i < numSegments; i++) {

                var segment = segments[i];
                var otherSegment = otherSegments[i];

                // as soon as an inequality is found in segments, return false
                if ((segment.type !== otherSegment.type) || (!segment.equals(otherSegment))) return false;
            }

            // if no inequality found in segments, return true
            return true;
        }
114406
function () {						// <<<<<< public
		var newMono, newMonoTo, toFirstOutSeg, fromRevSeg;
		for ( var i = 0, j = this.segments.length; i < j; i++) {
			newMono = this.segments[i];
			if ( this.PolyLeftArr[newMono.chainId] ) {
				// preserve winding order
				newMonoTo = newMono.vTo;			// target of segment
				newMono.mprev = newMono.sprev;		// doubly linked list for monotone chains (sub-polygons)
				newMono.mnext = newMono.snext;
			} else {
				// reverse winding order
				newMonoTo = newMono.vFrom;
				newMono = newMono.snext;
				newMono.mprev = newMono.snext;
				newMono.mnext = newMono.sprev;
			}
			if ( fromRevSeg = newMono.vFrom.lastInDiag ) {		// assignment !
				fromRevSeg.mnext = newMono;
				newMono.mprev = fromRevSeg;
				newMono.vFrom.lastInDiag = null;		// cleanup
			}
			if ( toFirstOutSeg = newMonoTo.firstOutDiag ) {		// assignment !
				toFirstOutSeg.mprev = newMono;
				newMono.mnext = toFirstOutSeg;
				newMonoTo.firstOutDiag = null;			// cleanup
			}
		}
	}
899507
public static void setByte(MemorySegment[] segments, int offset, byte value) {
		if (inFirstSegment(segments, offset, 1)) {
			segments[0].put(offset, value);
		} else {
			setByteMultiSegments(segments, offset, value);
		}
	}