Count of XREFs used by two trees at the same time.

@param Tree $tree1
@param Tree $tree2

@return int
964508
private function countCommonXrefs(Tree $tree1, Tree $tree2): int
    {
        $subquery1 = DB::table('individuals')
            ->where('i_file', '=', $tree1->id())
            ->select(['i_id AS xref'])
            ->union(DB::table('families')
                ->where('f_file', '=', $tree1->id())
                ->select(['f_id AS xref']))
            ->union(DB::table('sources')
                ->where('s_file', '=', $tree1->id())
                ->select(['s_id AS xref']))
            ->union(DB::table('media')
                ->where('m_file', '=', $tree1->id())
                ->select(['m_id AS xref']))
            ->union(DB::table('other')
                ->where('o_file', '=', $tree1->id())
                ->whereNotIn('o_type', ['HEAD', 'TRLR'])
                ->select(['o_id AS xref']));

        $subquery2 = DB::table('change')
            ->where('gedcom_id', '=', $tree2->id())
            ->select(['xref AS other_xref'])
            ->union(DB::table('individuals')
                ->where('i_file', '=', $tree2->id())
                ->select(['i_id AS xref']))
            ->union(DB::table('families')
                ->where('f_file', '=', $tree2->id())
                ->select(['f_id AS xref']))
            ->union(DB::table('sources')
                ->where('s_file', '=', $tree2->id())
                ->select(['s_id AS xref']))
            ->union(DB::table('media')
                ->where('m_file', '=', $tree2->id())
                ->select(['m_id AS xref']))
            ->union(DB::table('other')
                ->where('o_file', '=', $tree2->id())
                ->whereNotIn('o_type', ['HEAD', 'TRLR'])
                ->select(['o_id AS xref']));

        return DB::table(DB::raw('(' . $subquery1->toSql() . ') AS sub1'))
            ->mergeBindings($subquery1)
            ->joinSub($subquery2, 'sub2', 'other_xref', '=', 'xref')
            ->count();
    }
913086
private function allSources(Tree $tree): Collection
    {
        return DB::table('sources')
            ->where('s_file', '=', $tree->id())
            ->get()
            ->map(Source::rowMapper())
            ->filter(GedcomRecord::accessFilter());
    }
1303832
public function countChildren( $nsPrefix = NULL )
	{
		$i = 0;
		foreach( $this->children( $nsPrefix, TRUE ) as $node )
			$i++;
		return $i;
	}
7964
public function select2Submitter(ServerRequestInterface $request, Tree $tree): ResponseInterface
    {
        $page  = (int) $request->get('page');
        $query = $request->get('q', '');

        // Fetch one more row than we need, so we can know if more rows exist.
        $offset = $page * self::RESULTS_PER_PAGE;
        $limit  = self::RESULTS_PER_PAGE + 1;

        $results = $this->search_service
            ->searchSubmitters([$tree], [$query], $offset, $limit)
            ->map(static function (GedcomRecord $submitter): array {
                return [
                    'id'    => $submitter->xref(),
                    'text'  => view('selects/submitter', ['submitter' => $submitter]),
                    'title' => ' ',
                ];
            });

        return response([
            'results'    => $results->slice(0, self::RESULTS_PER_PAGE)->all(),
            'pagination' => [
                'more' => $results->count() > self::RESULTS_PER_PAGE,
            ],
        ]);
    }
1321101
public function reorderChildrenAction(ServerRequestInterface $request, Tree $tree): ResponseInterface
    {
        $xref   = $request->get('xref', '');
        $order  = (array) $request->get('order', []);
        $family = Family::getInstance($xref, $tree);

        Auth::checkFamilyAccess($family, true);

        $dummy_facts = ['0 @' . $family->xref() . '@ FAM'];
        $sort_facts  = [];
        $keep_facts  = [];

        // Split facts into FAMS and other
        foreach ($family->facts() as $fact) {
            if ($fact->getTag() === 'CHIL') {
                $sort_facts[$fact->id()] = $fact->gedcom();
            } else {
                $keep_facts[] = $fact->gedcom();
            }
        }

        // Sort the facts
        uksort($sort_facts, static function ($x, $y) use ($order) {
            return array_search($x, $order, true) - array_search($y, $order, true);
        });

        // Merge the facts
        $gedcom = implode("\n", array_merge($dummy_facts, $sort_facts, $keep_facts));

        $family->updateRecord($gedcom, false);

        return redirect($family->url());
    }
401283
private function checkLink(Tree $tree, string $xref): string
    {
        return '<b><a href="' . e(route('record', [
                'xref' => $xref,
                'ged'  => $tree->name(),
            ])) . '">' . $xref . '</a></b>';
    }
741656
private function comparePreReleaseIdentifier($identifier1, $identifier2) : int
    {
        $mineIsInt  = $this->isIdentifierInt($identifier1);
        $theirIsInt = $this->isIdentifierInt($identifier2);

        if ($mineIsInt !== $theirIsInt) {
            return $mineIsInt ? -1 : 1;
        }

        if ($mineIsInt) {
            return ((int) $identifier1) <=> ((int) $identifier2);
        }

        return $identifier1 <=> $identifier2;
    }
381558
public static function mungeFiles($file1, $file2) {
    $file1_contents = (array) self::parseFile($file1);
    $file2_contents = (array) self::parseFile($file2);

    return self::arrayMergeRecursiveExceptEmpty($file1_contents, $file2_contents);
  }
67988
public static function getDistanceBetweenXPaths($xpath1, $xpath2)
    {
        if (strlen($xpath1) > strlen($xpath2))
        {
            $diff = substr($xpath1, strlen($xpath2));
        }
        else
        {
            $diff = substr($xpath2, strlen($xpath1));
        }

        return count(explode('/', $diff));
    }
253600
function countSubTreeDepth(scope) {
          var thisLevelDepth = 0,
              childNodes = scope.childNodes(),
              childNode,
              childDepth,
              i;
          if (!childNodes || childNodes.length === 0) {
            return 0;
          }
          for (i = childNodes.length - 1; i >= 0 ; i--) {
            childNode = childNodes[i],
            childDepth = 1 + countSubTreeDepth(childNode);
            thisLevelDepth = Math.max(thisLevelDepth, childDepth);
          }
          return thisLevelDepth;
        }
209969
def fast_compare(tree1, tree2):
    

    geta = ast.AST.__getattribute__

    work = [(tree1, tree2)]
    pop = work.pop
    extend = work.extend
    # TypeError in cPython, AttributeError in PyPy
    exception = TypeError, AttributeError
    zipl = zip_longest
    type_ = type
    list_ = list
    while work:
        n1, n2 = pop()
        try:
            f1 = geta(n1, '_fields')
            f2 = geta(n2, '_fields')
        except exception:
            if type_(n1) is list_:
                extend(zipl(n1, n2))
                continue
            if n1 == n2:
                continue
            return False
        else:
            f1 = [x for x in f1 if x != 'ctx']
            if f1 != [x for x in f2 if x != 'ctx']:
                return False
            extend((geta(n1, fname), geta(n2, fname)) for fname in f1)

    return True
1097573
public function select2Note(ServerRequestInterface $request, Tree $tree): ResponseInterface
    {
        $page  = (int) $request->get('page');
        $query = $request->get('q', '');

        // Fetch one more row than we need, so we can know if more rows exist.
        $offset = $page * self::RESULTS_PER_PAGE;
        $limit  = self::RESULTS_PER_PAGE + 1;

        $results = $this->search_service
            ->searchNotes([$tree], [$query], $offset, $limit)
            ->map(static function (Note $note): array {
                return [
                    'id'    => $note->xref(),
                    'text'  => view('selects/note', ['note' => $note]),
                    'title' => ' ',
                ];
            });

        return response([
            'results'    => $results->slice(0, self::RESULTS_PER_PAGE)->all(),
            'pagination' => [
                'more' => $results->count() > self::RESULTS_PER_PAGE,
            ],
        ]);
    }
441969
public function statsMarriageQuery(int $year1 = -1, int $year2 = -1): Builder
    {
        $query = DB::table('dates')
            ->where('d_file', '=', $this->tree->id())
            ->where('d_fact', '=', 'MARR')
            ->select(['d_month', DB::raw('COUNT(*) AS total')])
            ->groupBy('d_month');

        if ($year1 >= 0 && $year2 >= 0) {
            $query->whereBetween('d_year', [$year1, $year2]);
        }

        return $query;
    }
123791
public static function accessLevel(Tree $tree, UserInterface $user = null): int
    {
        $user = $user ?? self::user();

        if (self::isManager($tree, $user)) {
            return self::PRIV_NONE;
        }

        if (self::isMember($tree, $user)) {
            return self::PRIV_USER;
        }

        return self::PRIV_PRIVATE;
    }
791128
private function duplicateRecords(Tree $tree): array
    {
        // We can't do any reasonable checks using MySQL.
        // Will need to wait for a "repositories" table.
        $repositories = [];

        $sources = DB::table('sources')
            ->where('s_file', '=', $tree->id())
            ->groupBy('s_name')
            ->having(DB::raw('COUNT(s_id)'), '>', 1)
            ->select([DB::raw('GROUP_CONCAT(s_id) AS xrefs')])
            ->pluck('xrefs')
            ->map(static function (string $xrefs) use ($tree): array {
                return array_map(static function (string $xref) use ($tree): Source {
                    return Source::getInstance($xref, $tree);
                }, explode(',', $xrefs));
            })
            ->all();

        $individuals = DB::table('dates')
            ->join('name', static function (JoinClause $join): void {
                $join
                    ->on('d_file', '=', 'n_file')
                    ->on('d_gid', '=', 'n_id');
            })
            ->where('d_file', '=', $tree->id())
            ->whereIn('d_fact', ['BIRT', 'CHR', 'BAPM', 'DEAT', 'BURI'])
            ->groupBy('d_year')
            ->groupBy('d_month')
            ->groupBy('d_day')
            ->groupBy('d_type')
            ->groupBy('d_fact')
            ->groupBy('n_type')
            ->groupBy('n_full')
            ->having(DB::raw('COUNT(DISTINCT d_gid)'), '>', 1)
            ->select([DB::raw('GROUP_CONCAT(d_gid) AS xrefs')])
            ->pluck('xrefs')
            ->map(static function (string $xrefs) use ($tree): array {
                return array_map(static function (string $xref) use ($tree): Individual {
                    return Individual::getInstance($xref, $tree);
                }, explode(',', $xrefs));
            })
            ->all();

        $families = DB::table('families')
            ->where('f_file', '=', $tree->id())
            ->groupBy(DB::raw('LEAST(f_husb, f_wife)'))
            ->groupBy(DB::raw('GREATEST(f_husb, f_wife)'))
            ->having(DB::raw('COUNT(f_id)'), '>', 1)
            ->select([DB::raw('GROUP_CONCAT(f_id) AS xrefs')])
            ->pluck('xrefs')
            ->map(static function (string $xrefs) use ($tree): array {
                return array_map(static function (string $xref) use ($tree): Family {
                    return Family::getInstance($xref, $tree);
                }, explode(',', $xrefs));
            })
            ->all();

        $media = DB::table('media_file')
            ->where('m_file', '=', $tree->id())
            ->where('descriptive_title', '<>', '')
            ->groupBy('descriptive_title')
            ->having(DB::raw('COUNT(m_id)'), '>', 1)
            ->select([DB::raw('GROUP_CONCAT(m_id) AS xrefs')])
            ->pluck('xrefs')
            ->map(static function (string $xrefs) use ($tree): array {
                return array_map(static function (string $xref) use ($tree): Media {
                    return Media::getInstance($xref, $tree);
                }, explode(',', $xrefs));
            })
            ->all();

        return [
            I18N::translate('Repositories')  => $repositories,
            I18N::translate('Sources')       => $sources,
            I18N::translate('Individuals')   => $individuals,
            I18N::translate('Families')      => $families,
            I18N::translate('Media objects') => $media,
        ];
    }
1332720
public function setSource($xref){
		if($xref instanceof Source){
			$this->source = $xref;
		} else {
			$this->source = Source::getInstance($xref, $this->tree);
		}
	}
1268106
protected function shared($path1, $path2)
    {
        // $path could theoretically be empty (e.g. no path is given), in which
        // case it shouldn't expand to array(''), which would compare to one's
        // root /
        $path1 = $path1 ? explode('/', $path1) : array();
        $path2 = $path2 ? explode('/', $path2) : array();

        $shared = array();

        // compare paths & strip identical ancestors
        foreach ($path1 as $i => $chunk) {
            if (isset($path2[$i]) && $path1[$i] == $path2[$i]) {
                $shared[] = $chunk;
            } else {
                break;
            }
        }

        return implode('/', $shared);
    }