123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106(*
* Copyright (c) 2013-2017 Thomas Gazagnaire <thomas@gazagnaire.org>
* and Romain Calascibetta <romain.calascibetta@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openLwt.InfixmoduleMake(Hash:Digestif.S)(Store:Minimal.Swithtypehash=Hash.t)=structtypehash=Hash.ttypestore=Store.tmoduleLog=structletsrc=Logs.Src.create"git.search"~doc:"logs git's internal search computation"include(valLogs.src_logsrc:Logs.LOG)endtypepred=[`Commitofhash|`Tagofstring*hash|`Treeofstring*hash|`Tree_rootofhash]letpredt?(full=true)h=lettagt=`Tag(Store.Value.Tag.tagt,Store.Value.Tag.objt)inLog.debug(funl->l~header:"predecessor""Read the object: %a."Hash.pph);Store.read_exnth>>=function|Value.Blob_->Lwt.return[]|Value.Commitc->(Store.is_shallowedth>|=function|true->iffullthen[`Tree_root(Store.Value.Commit.treec)]else[]|false->(iffullthen[`Tree_root(Store.Value.Commit.treec)]else[])@List.map(funx->`Commitx)(Store.Value.Commit.parentsc))|Value.Tagt->iffullthenLwt.return[tagt]elseLwt.return[]|Value.Treet->iffullthenletlst=List.map(fun{Tree.name;node;_}->`Tree(name,node))(Store.Value.Tree.to_listt)inLwt.returnlstelseLwt.return[]typepath=[`Tagofstring*path|`Commitofpath|`Pathofstringlist]letfind_listfl=List.fold_left(funaccx->matchaccwithSome_->acc|None->fx)Nonellet_find_commit=find_list(function`Commitx->Somex|_->None)letfind_tree_root=find_list(function`Tree_rootx->Somex|_->None)letfind_tagl=find_list(function|`Tag(s,x)->ifl=sthenSomexelseNone|_->None)letfind_treel=find_list(function|`Tree(s,x)->ifs=lthenSomexelseNone|_->None)letrecfindthashpath=matchpathwith|`Path[]->Lwt.return(Somehash)|`Tag(l,p)->(predthash>>=funpreds->matchfind_taglpredswith|None->Lwt.return_none|Somes->(find[@tailcall])tsp)|`Commitp->(predthash>>=funpreds->matchfind_tree_rootpredswith|None->Lwt.return_none|Somes->(find[@tailcall])tsp)|`Path(h::p)->(predthash>>=funpreds->matchfind_treehpredswith|None->Lwt.return_none|Somes->(find[@tailcall])ts(`Pathp))(* XXX: can do one less look-up *)letmemthpath=findthpath>>=function|None->Lwt.returnfalse|Some_->Lwt.returntrueend