%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /www/varak.net/nextcloud.varak.net/apps/photos/vendor/hexogen/kdtree/src/
Upload File :
Create Path :
Current File : //www/varak.net/nextcloud.varak.net/apps/photos/vendor/hexogen/kdtree/src/FSTreePersister.php

<?php

namespace Hexogen\KDTree;

use Hexogen\KDTree\Interfaces\ItemInterface;
use Hexogen\KDTree\Interfaces\KDTreeInterface;
use Hexogen\KDTree\Interfaces\NodeInterface;
use Hexogen\KDTree\Interfaces\TreePersisterInterface;

class FSTreePersister implements TreePersisterInterface
{
    /**
     * @var string path to the file
     */
    private $path;

    /**
     * @var resource file handler
     */
    private $handler;

    /**
     * @var int
     */
    private $dimensions;

    /**
     * @var int
     */
    private $nodeMemorySize;

    public function __construct(string $path)
    {
        $this->path = $path;
    }

    /**
     * @api
     * @param KDTreeInterface $tree
     * @param string $identifier that identifies persisted tree(may be a filename, database name etc.)
     * @return mixed
     */
    public function convert(KDTreeInterface $tree, string $identifier)
    {
        $this->initTree($identifier);

        $this->dimensions = $tree->getDimensionCount();

        $this->calculateNodeSize();

        $this->specifyNumberOfDimensions();

        $this->specifyNumberOfItems($tree);

        $upperBound = $tree->getMaxBoundary();
        $this->writeCoordinate($upperBound);

        $lowerBound = $tree->getMinBoundary();
        $this->writeCoordinate($lowerBound);

        $root  = $tree->getRoot();
        if ($root) {
            $this->writeNode($root);
        }
        fclose($this->handler);
    }

    /**
     * @param NodeInterface $node
     */
    private function writeNode(NodeInterface $node)
    {
        $position = ftell($this->handler);
        $item = $node->getItem();

        $this->writeItemId($item);

        $dataChunk = pack('V', 0); // left position currently unknown so it equal 0/null
        fwrite($this->handler, $dataChunk);

        $rightNode = $node->getRight();

        $rightPosition = 0;
        if ($rightNode) {
            $rightPosition = $position + $this->nodeMemorySize;
        }
        $dataChunk = pack('V', $rightPosition);
        fwrite($this->handler, $dataChunk);

        $this->saveItemCoordinate($item);

        if ($rightNode) {
            $this->writeNode($rightNode);
        }

        $leftNode = $node->getLeft();

        if ($leftNode == null) {
            return;
        }
        $this->persistLeftLink($position);
        $this->writeNode($leftNode);
    }

    /**
     * @param array $coordinate
     */
    private function writeCoordinate(array $coordinate)
    {
        $dataChunk = pack('d'.$this->dimensions, ...$coordinate);
        fwrite($this->handler, $dataChunk);
    }

    /**
     * @param string $identifier
     */
    private function initTree(string $identifier)
    {
        $this->handler = fopen($this->path . '/' . $identifier, 'wb');
    }

    /**
     * Calculate memory size in file needed for single node
     */
    private function calculateNodeSize()
    {
        $this->nodeMemorySize = 3 * FSKDTree::INT_LENGTH + $this->dimensions * FSKDTree::FLOAT_LENGTH;
    }

    /**
     * Specify number of dimensions according to file format
     */
    private function specifyNumberOfDimensions()
    {
        $dataChunk = pack('V', $this->dimensions);
        fwrite($this->handler, $dataChunk);
    }

    /**
     * @param KDTreeInterface $tree
     */
    private function specifyNumberOfItems(KDTreeInterface $tree)
    {
        $itemCount = $tree->getItemCount();
        $dataChunk = pack('V', $itemCount);
        fwrite($this->handler, $dataChunk);
    }

    /**
     * @param $item
     */
    private function saveItemCoordinate(ItemInterface $item)
    {
        $coordinate = [];
        for ($i = 0; $i < $this->dimensions; $i++) {
            $coordinate[] = $item->getNthDimension($i);
        }
        $this->writeCoordinate($coordinate);
    }

    /**
     * Persist current position before writing left node
     * @param int $position
     */
    private function persistLeftLink(int $position)
    {
        $leftPosition = ftell($this->handler);
        fseek($this->handler, $position + FSKDTree::INT_LENGTH);
        $dataChunk = pack('V', $leftPosition);
        fwrite($this->handler, $dataChunk);
        fseek($this->handler, $leftPosition);
    }

    /**
     * @param $item
     */
    private function writeItemId(ItemInterface $item)
    {
        $itemId = $item->getId();
        $dataChunk = pack('V', $itemId);
        fwrite($this->handler, $dataChunk);
    }
}

Zerion Mini Shell 1.0