1 pontos por GN⁺ 2025-02-26 | 1 comentários | Compartilhar no WhatsApp
  • A limpeza de arquivos duplicados no Mac normalmente pressupõe exclusão, mas o Hyperspace usa clones APFS para fazer arquivos com o mesmo conteúdo compartilharem dados, recuperando espaço sem remover os arquivos
  • Os clones copy-on-write do APFS, como o “Duplicate” do Finder, compartilham os dados com o original sem regravar os dados reais, fazendo com que até cópias grandes terminem quase instantaneamente
  • Quando o disco do desenvolvedor começou a encher, ele criou um script em Perl para encontrar arquivos com o mesmo conteúdo que não eram clones; o espaço potencialmente economizável apareceu como dezenas de GB, e isso evoluiu para um app
  • O app pode ser baixado gratuitamente para fazer a varredura e verificar o espaço que pode ser economizado, mas a recuperação efetiva de espaço exige pagamento
  • Como ele modifica arquivos que não foram criados nem são de propriedade do app, o risco é alto, mas por isso mesmo pode oferecer ajuda prática a muitos usuários de Mac

Recuperar espaço mantendo os arquivos com clones APFS

  • Quando arquivos com o mesmo conteúdo não têm relação de clone entre si, o Hyperspace os transforma em clones APFS para que compartilhem apenas uma cópia dos dados no disco
  • Apps tradicionais de arquivos duplicados para Mac geralmente encontram arquivos duplicados e os apagam para economizar espaço, mas o Hyperspace recupera espaço sem remover arquivos
  • Entre os principais recursos do APFS estão snapshots de ponto no tempo e clones copy-on-write
    • Snapshots são usados para tornar os backups do Time Machine mais estáveis e eficientes
    • Clones copy-on-write se baseiam em uma estrutura flexível entre entradas de diretório e o conteúdo dos arquivos
  • Ao duplicar um arquivo no Finder com o comando “Duplicate”, o conteúdo real do arquivo não é copiado; é criado um arquivo clone que compartilha os dados com o original
    • Graças a essa estrutura, a duplicação no Finder termina quase instantaneamente, independentemente do tamanho do arquivo

Modelo de lançamento e notas de desenvolvimento

  • No fim de 2024, quando o disco do seu Mac começou a encher, o desenvolvedor escreveu um script em Perl que encontrava arquivos não clonados com o mesmo conteúdo e os convertia em clones
    • O script chama uma ferramenta de linha de comando escrita em C e uma ferramenta de linha de comando escrita em Swift
    • O resultado da execução mostrou dezenas de GB de espaço potencialmente economizável, e depois isso evoluiu para um app para Mac
  • Hyperspace está disponível na Mac App Store
  • Do ponto de vista de desenvolvimento, o Hyperspace é o segundo app para Mac em SwiftUI do desenvolvedor e o primeiro a usar o SwiftUI life cycle
    • Também é seu segundo app usando Swift 6
    • Usar Swift 6 desde o início do desenvolvimento foi muito mais fácil do que migrar para Swift 6 um app já lançado
    • O Swift 6 ainda tem muitas arestas, e ele espera melhorias futuras
  • O Hyperspace modifica arquivos que o app não criou e dos quais não é proprietário, como no processo de conversão de HFS+ para APFS
    • O desenvolvedor o chama de app mais perigoso que já criou
    • Ao mesmo tempo, considera que pode ser o app mais útil para o maior número de pessoas

1 comentários

 
GN⁺ 2025-02-26
Comentários no Hacker News
  • Há algum tempo fiz um utilitário de linha de comando chamado dedup que faz a mesma coisa
    Tem modo dry-run, escolhe “inteligentemente” a melhor origem do clone, entende hard links e outros clones, preserva metadados e também lida corretamente com arquivos compactados em HFS
    Ainda não corrompi meus dados, mas, como sempre acontece com ferramentas de sistema de arquivos, use por sua conta e risco
    0 - https://github.com/ttkb-oss/dedup

    • Escrevendo isso depois de só fazer a varredura, sem ainda remover duplicatas, a diferença já aparece bastante em um workspace de 7.6GB com imagens de disco, binários de programas e representações intermediárias
      O Hyperspace, por padrão, não varre todos os arquivos e olha apenas os arquivos em uma lista de permissões, além de parecer ter uma estrutura que precisa entender o conteúdo dos arquivos. Do ponto de vista do usuário final, não sei como ele distingue arquivos de texto de arquivos de código-fonte, e a varredura padrão encontrou apenas 360MB como candidatos à deduplicação, mas permitindo todos os arquivos isso subiu para 842MB
      Por padrão, ele também não varre arquivos menores que 100KB; desativando esse limite de tamanho e permitindo todos os arquivos, o total subiu para 1.1GB. Sem limite de tipo nem de tamanho, o Hyperspace examinou 67.309 de 68.874 arquivos, e o dedup examinou 67.426
      O Hyperspace disse que 29.522 arquivos podiam ser deduplicados, e o dedup encontrou 29.447. Há uma diferença de um arquivo porque 76 já estavam deduplicados, mas não sei a causa exata
      O tempo de varredura foi de cerca de 50 segundos no Hyperspace e 14 segundos no dedup. O Hyperspace parece varrer o sistema de arquivos, depois calcular as duplicatas e só então fazer a deduplicação; não entendo por que não juntar as duas primeiras etapas. Eu coloquei os metadados do sistema de arquivos em uma fila durante a varredura e comecei o cálculo das duplicatas em paralelo, e na maioria dos casos já dá para filtrar incompatibilidades só com a informação de tamanho obtida “de graça” ao percorrer diretórios com fts_read
      O Hyperspace disse que podia economizar 1.1GB, e o dedup encontrou 1.04GB mais 882MB já economizados. Não pretendo comprar o Hyperspace, então não sei sobre o tempo real de deduplicação, preservação de metadados ou tratamento de arquivos estranhos, mas o dedup levou 31 segundos no total, somando varredura e deduplicação
      Mesmo depois de deduplicar com dedup, o Hyperscan ainda considerou que havia 2 arquivos deduplicáveis. O Hyperspace também parece lidar com arquivos com vários hard links, arquivos vazios e várias exceções que o dedup verifica. Não dá para testar a preservação de ACL ou outros atributos sem pagar, mas pelo strings parece que ele trata isso, e a compactação HFS é um caso de borda complicado, então ainda não confirmei como a varredura do Hyperspace lida com isso
    • Ao rodar em um lugar com muitos arquivos quase iguais, como um diretório de desenvolvimento do Postgres, economizei cerca de 1.7GB
      O projeto não tem licença, então, se possível, seria bom adicionar a licença que você quiser. Também fiz um pull request para tentar melhorar um pouco a etapa de instalação: https://github.com/ttkb-oss/dedup/pull/6
    • Acabei de usar e funcionou bem. Só depois de ver quanta duplicação existe em certos tipos de arquivo, especialmente dentro de node_modules, percebi o potencial dessa técnica
      Mesmo olhando só subdiretórios específicos, não era raro transformar 50 cópias de algum arquivo JS em uma só. Mas, como está em “pre-release” e tem poucas estrelas no GitHub, fico curioso sobre a estabilidade, porque esse tipo de ferramenta é bem assustador se tiver bugs
    • A documentação é excelente, e também me impressionou o fato de que o make termina quase instantaneamente
    • Para uma lista de alternativas, veja os comentários em https://news.ycombinator.com/item?id=38113396
      Já usei https://github.com/sahib/rmlint antes e não tive nenhuma reclamação
  • Ao ver a parte dizendo que “o Hyperspace não tem como coordenar com todos os outros apps ou com o próprio macOS para determinar um momento seguro para substituir arquivos, nem tem como forçar controle exclusivo sobre esse arquivo”, fiquei pensando por que o próprio sistema de arquivos não executa em segundo plano um processo de desduplicação parecido
    Nesse nível de abstração, parece que daria para gerenciar essas questões de segurança, então fico imaginando quais seriam as desvantagens de isso acontecer automaticamente dentro do APFS

    • No ZFS, isso consome muita RAM. Imagino que seja porque o ZFS opera no nível de bloco, então precisa rastrear muitos blocos para comparar quando um novo bloco é gravado
      Se fosse implementado no nível de arquivo, talvez o uso de recursos caísse, mas não sei se a implementação ficaria mais simples ou mais complexa. Também pode não ser intuitivo que, em arquivos grandes, mudar só 1 byte pode fazer o sistema de arquivos ter de duplicar o arquivo de novo, gerando muita atividade de disco
    • Em dispositivos de armazenamento em bloco, esse tipo de coisa é comum junto com compressão. Claro, isso falha se o sistema de arquivos criptografar os blocos antes de enviá-los ao dispositivo
      Fazer a desduplicação nessa camada é bom porque permite desduplicar entre vários sistemas de arquivos. Por exemplo, se houver mil sistemas com os mesmos arquivos do sistema operacional, dá para economizar um enorme espaço de armazenamento, e muitas vezes as diferenças se resumem a configurações específicas da máquina, como chave do host ou nome do host. Um único sistema de arquivos não consegue perceber esse tipo de semelhança
      Por outro lado, vira problema se a desduplicação reduzir o número de cópias de arquivos muito usados. No exemplo acima, se as mil máquinas inicializarem ao mesmo tempo, pode haver uma carga de I/O enorme sobre a imagem do kernel
    • No Linux, essa é a API de desduplicação padrão usada pelo btrfs e pelo XFS
      Você solicita educadamente ao sistema operacional que desduplique um conjunto de intervalos especificado, e o SO bloqueia esses intervalos e só faz a desduplicação depois de verificar que eles são realmente idênticos. Ele também devolve em campos quantos bytes foram desduplicados em cada intervalo, então não há como um programa em espaço de usuário corromper os arquivos
    • O ZFS realmente faz esse tipo de coisa: https://www.truenas.com/docs/references/zfsdeduplication/
    • O Windows Server também oferece esse recurso em volumes NTFS e ReFS
      Usei bastante isso em ReFS com VMs do Hyper-V, e o resultado foi impressionante. Na época, a maioria das VMs misturava Windows Server 2016/2019, e isso reduziu o uso de armazenamento em cerca de 45%
  • Gosto do modelo em que o scan é gratuito para verificar se vale a pena, e só se paga pelo resultado real
    Também costumo acumular arquivos, então rodei aqui e apareceu 7 GB recuperáveis, mas para mim isso não justificava pagar. Ainda assim, é bom que exista uma ferramenta assim

    • Isso já foi explicado em um podcast. Como muita gente vai comprar isso, rodar uma vez, economizar alguns GB e pronto, assinatura não faz muito sentido
      Afinal, quantos arquivos duplicados exatamente iguais alguém realmente cria por engano a cada mês?
      Até existem opções de assinatura ou compra permanente para quem vai usar com frequência, mas para muita gente uma compra única dentro do app para usar por um período limitado é bem razoável. E você sempre pode rodar de novo de graça para ver se já acumulou o bastante para justificar pagar outra vez
    • Para mim, o valor de um app de desduplicação está menos na economia de espaço e mais em não deixar arquivos duplicados sobrando
      Não chego a gerar quantidades absurdas, mas alguns arquivos grandes podem acabar duplicados parcial ou totalmente. Isso geralmente acontece em situações estranhas, como quando preciso comparar o resultado de uma recuperação de HD com arquivos em outros lugares, ou quando preciso bater uma pasta de downloads bagunçada com um destino mais organizado
      Por exemplo, já tive um backup do Time Machine que trouxe versões antigas de arquivos que eu nem sabia que tinha registro e achava que tinha perdido há muito tempo, mas estragou os nomes dos diretórios e também deixou o conteúdo meio ofuscado. Havia milhares de diretórios com nomes numéricos e, dentro deles, talvez arquivos que eu quisesse guardar, mas sem nenhuma estrutura para saber se eu já os tinha ou onde estavam. Por outro lado, muitas vezes havia apenas um único arquivo de texto do sistema de build, então esses obviamente davam para descartar
    • Fico pensando se estou velho por lembrar que, há 10 anos, a maioria dos softwares funcionava assim
      Será que as pessoas já se acostumaram tanto com a armadilha das assinaturas que isso parece um modelo novo?
    • Gosto muito desse modelo de preço
      Seria ótimo se fosse fácil fazer isso em outros tipos de software também, mas normalmente a curva de aprendizado atrapalha até você perceber o valor
    • É muito mais refrescante do que um “teste grátis” que você precisa lembrar de cancelar
      Uma dica: use um cartão virtual bloqueável nesses testes, assim, se você esquecer de cancelar, a cobrança não passa. Dito isso, fico curioso se alguém conseguiu encontrar no site o preço real da licença
  • Fico curioso sobre qual algoritmo o app usa para descobrir se dois arquivos são idênticos
    Há várias abordagens interessantes, como hash, comparação bit a bit etc., mas cada uma tem suas desvantagens. Qual seria o melhor método quando há muitos arquivos?

    • Não sei exatamente o que o Siracusa faz, mas dá para especular
      Para cada arquivo candidato, é preciso uma “chave” para verificar se ele é igual a outros candidatos. Como podem existir milhões de arquivos, essa chave precisa ser pequena e rápida de gerar, mas ao mesmo tempo não pode ter falsos positivos
      Hoje, a resposta mais óbvia é o hash SHA256 do conteúdo do arquivo. É muito rápido, tem só 32 bytes, o que nem é tão grande, e a chance de falso positivo ou colisão é tão baixa que o mundo acabaria antes de você esbarrar nisso na prática. SHA256 é praticamente o padrão de fato para esse tipo de uso, então eu ficaria bem surpreso se fosse outra coisa
    • Isso me lembrou o https://en.wikipedia.org/wiki/Venti_(software)
      Era um sistema de arquivos endereçado por conteúdo que usava hash para desduplicação, e como o hash era calculado no momento da gravação, o custo de desempenho ficava distribuído
    • Eu faria hash dos primeiros 1024 bytes de todos os arquivos e só avançaria além disso quando houvesse colisão
      Assim não seria preciso calcular hash do arquivo grande inteiro, e só os arquivos com o mesmo hash precisariam de verificação adicional
  • A Apple também fornece uma versão modificada do comando cp com suporte à flag -c para usar o recurso de clonagem do APFS

    • Se o cp que você usa não der suporte a isso, também dá para chamar via Python
      Por exemplo, algo como import Foundation; Foundation.NSFileManager.defaultManager().copyItemAtPath_toPath_error_(...)
  • Se o arquivo A estiver em dois locais e, depois de executar isso, A_0 for modificado, fiquei curioso se A_1 também muda junto ou se apenas o novo estado de A_0 é materializado e A_1 permanece como está

  • Antes de a Apple anunciar o APFS na WWDC 2017, me chamou atenção a parte em que ela teria testado secretamente a conversão de todos os iPhones para APFS como parte de uma atualização do iOS 10.x, e depois voltado para HFS+
    Fiquei curioso sobre como é possível reverter quando uma mudança de sistema de arquivos dá errado. Dá para validar bastante o código, mas parece que, se algo der problema, não tem como desfazer

    • Se bem me lembro, a migração de HFS+ para APFS pode ser feita sem mexer nos blocos de dados, gravando blocos de metadados e superblocos do APFS em paralelo no disco
      No teste de migração da Apple, eles executaram a migração completa, inclusive criando o superbloco do APFS, mas pararam imediatamente antes do commit que substituiria permanentemente o superbloco do HFS+ pelo do APFS. Ao reverter, bastava “simplesmente” limpar o superbloco do APFS e os blocos de metadados criados
    • Vi essa parte da apresentação [0], e quase não há detalhes além de dizer que foi feito como teste de consistência
      Como alguém que já quebrou muita coisa em produção, não sei se eu conseguiria apertar o botão para rodar uma migração tão grande assim
      [0] https://www.youtube.com/watch?v=IcyaadNy9Jk&t=1670s
    • Acho que isso é falta de imaginação. Não é uma tecnologia de joia da coroa que só a Apple consegue fazer
      No mundo open source também existem ferramentas para converter sistemas de arquivos ext para btrfs, e elas (1) permitem reverter e (2) ainda permitem montar o sistema de arquivos ext original enquanto se usa o btrfs
  • Começa com uma história, afunila para um problema e depois mostra a solução resolvendo esse problema como se fosse mágica
    Um ótimo exemplo de excelente marketing

  • Rodei isso em uma pasta enorme de projeto NodeJS, mas apareceu que só seria possível economizar 1GB em uma pasta de 8.1GB
    Rodei de novo incluindo a pasta home do usuário, e o total foi de apenas 1.3GB economizados, considerando 731 mil arquivos, 127 mil pastas e 2.755 arquivos-alvo. Isso é só uns 300MB a mais do que quando rodei apenas na pasta do NodeJS
    Tentei escanear também System e Library, mas foi negado por causa de problemas de permissão. Como uso pnpm como gerenciador de pacotes, parece que o uso de disco já está quase no ideal
    A ideia é legal, mas é difícil justificar pelo preço atual; seria melhor se rodasse como um processo em segundo plano mais ou menos uma vez por mês

    • 1GB de 8.1GB não significa que 12% do espaço usado estava sendo desperdiçado? Será que entendi direito?
    • O pnpm busca ser um substituto direto do npm e faz desduplicação automaticamente
    • O macOS tem um volume selado, por isso esses erros de permissão aparecem em System e Library
      https://support.apple.com/guide/security/signed-system-volum...
    • Não tive tempo de testar pessoalmente, mas dá para ver claramente nas capturas da App Store uma opção de tamanho mínimo de arquivo a considerar
      Parece algo introduzido para reduzir o buffer de comparação, então é possível que os arquivos de node_modules fiquem abaixo desse tamanho e não tenham sido considerados
    • Não sei qual é o preço. Parece não estar divulgado em lugar nenhum
  • Já criei um script parecido, mas mais simples, que transforma arquivos com o mesmo conteúdo em hard links
    A principal motivação eram os pacotes de ambientes virtuais Python. É comum ter pacotes semelhantes instalados, e mesmo quando as versões são diferentes, muitos arquivos ainda coincidem. Alguns pacotes, como Numpy, PyTorch e TensorFlow, são bem grandes, então dava para economizar bastante espaço em disco
    https://github.com/albertz/system-tools/blob/master/bin/merg...

    • Isso não usa hard links nem links simbólicos, e sim o recurso do sistema de arquivos para criar clones copy-on-write [1]
      [1] https://en.wikipedia.org/wiki/Apple_File_System#Clones
    • O uv faz isso por padrão
      Imagino que outras ferramentas como poetry, hatch e pdm também façam, mas usei menos essas ferramentas e não conheço tão bem os detalhes de funcionamento