1 /* 2 * DirectorySubspace.cpp 3 * 4 * This source file is part of the FoundationDB open source project 5 * 6 * Copyright 2013-2018 Apple Inc. and the FoundationDB project authors 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 #include "DirectorySubspace.h" 22 23 namespace FDB { DirectorySubspace(Path const & path,StringRef const & prefix,Reference<DirectoryLayer> directoryLayer,Standalone<StringRef> const & layer)24 DirectorySubspace::DirectorySubspace(Path const& path, StringRef const& prefix, Reference<DirectoryLayer> directoryLayer, Standalone<StringRef> const& layer) 25 : Subspace(prefix), directoryLayer(directoryLayer), path(path), layer(layer) { } 26 27 create(Reference<Transaction> const & tr,Path const & path,Standalone<StringRef> const & layer,Optional<Standalone<StringRef>> const & prefix)28 Future<Reference<DirectorySubspace>> DirectorySubspace::create(Reference<Transaction> const& tr, Path const& path, Standalone<StringRef> const& layer, 29 Optional<Standalone<StringRef>> const& prefix) 30 { 31 return directoryLayer->create(tr, getPartitionSubpath(path), layer, prefix); 32 } 33 open(Reference<Transaction> const & tr,Path const & path,Standalone<StringRef> const & layer)34 Future<Reference<DirectorySubspace>> DirectorySubspace::open(Reference<Transaction> const& tr, Path const& path, Standalone<StringRef> const& layer) { 35 return directoryLayer->open(tr, getPartitionSubpath(path), layer); 36 } 37 createOrOpen(Reference<Transaction> const & tr,Path const & path,Standalone<StringRef> const & layer)38 Future<Reference<DirectorySubspace>> DirectorySubspace::createOrOpen(Reference<Transaction> const& tr, Path const& path, Standalone<StringRef> const& layer) { 39 return directoryLayer->createOrOpen(tr, getPartitionSubpath(path), layer); 40 } 41 exists(Reference<Transaction> const & tr,Path const & path)42 Future<bool> DirectorySubspace::exists(Reference<Transaction> const& tr, Path const& path) { 43 Reference<DirectoryLayer> directoryLayer = getDirectoryLayerForPath(path); 44 return directoryLayer->exists(tr, getPartitionSubpath(path, directoryLayer)); 45 } 46 list(Reference<Transaction> const & tr,Path const & path)47 Future<Standalone<VectorRef<StringRef>>> DirectorySubspace::list(Reference<Transaction> const& tr, Path const& path) { 48 return directoryLayer->list(tr, getPartitionSubpath(path)); 49 } 50 move(Reference<Transaction> const & tr,Path const & oldPath,Path const & newPath)51 Future<Reference<DirectorySubspace>> DirectorySubspace::move(Reference<Transaction> const& tr, Path const& oldPath, Path const& newPath) { 52 return directoryLayer->move(tr, getPartitionSubpath(oldPath), getPartitionSubpath(newPath)); 53 } 54 moveTo(Reference<Transaction> const & tr,Path const & newAbsolutePath)55 Future<Reference<DirectorySubspace>> DirectorySubspace::moveTo(Reference<Transaction> const& tr, Path const& newAbsolutePath) { 56 Reference<DirectoryLayer> directoryLayer = getDirectoryLayerForPath(Path()); 57 Path directoryLayerPath = directoryLayer->getPath(); 58 59 if(directoryLayerPath.size() > newAbsolutePath.size()) { 60 return cannot_move_directory_between_partitions(); 61 } 62 63 for(int i = 0; i < directoryLayerPath.size(); ++i) { 64 if(directoryLayerPath[i] != newAbsolutePath[i]) { 65 return cannot_move_directory_between_partitions(); 66 } 67 } 68 69 Path newRelativePath(newAbsolutePath.begin() + directoryLayerPath.size(), newAbsolutePath.end()); 70 return directoryLayer->move(tr, getPartitionSubpath(Path(), directoryLayer), newRelativePath); 71 } 72 remove(Reference<Transaction> const & tr,Path const & path)73 Future<Void> DirectorySubspace::remove(Reference<Transaction> const& tr, Path const& path) { 74 Reference<DirectoryLayer> directoryLayer = getDirectoryLayerForPath(path); 75 return directoryLayer->remove(tr, getPartitionSubpath(path, directoryLayer)); 76 } 77 removeIfExists(Reference<Transaction> const & tr,Path const & path)78 Future<bool> DirectorySubspace::removeIfExists(Reference<Transaction> const& tr, Path const& path) { 79 Reference<DirectoryLayer> directoryLayer = getDirectoryLayerForPath(path); 80 return directoryLayer->removeIfExists(tr, getPartitionSubpath(path, directoryLayer)); 81 } 82 getDirectoryLayer()83 Reference<DirectoryLayer> DirectorySubspace::getDirectoryLayer() { 84 return directoryLayer; 85 } 86 getLayer() const87 const Standalone<StringRef> DirectorySubspace::getLayer() const { 88 return layer; 89 } 90 getPath() const91 const IDirectory::Path DirectorySubspace::getPath() const { 92 return path; 93 } 94 getPartitionSubpath(Path const & path,Reference<DirectoryLayer> directoryLayer) const95 IDirectory::Path DirectorySubspace::getPartitionSubpath(Path const& path, Reference<DirectoryLayer> directoryLayer) const { 96 if(!directoryLayer) { 97 directoryLayer = this->directoryLayer; 98 } 99 100 Path newPath(this->path.begin() + directoryLayer->getPath().size(), this->path.end()); 101 newPath.insert(newPath.end(), path.begin(), path.end()); 102 103 return newPath; 104 } 105 getDirectoryLayerForPath(Path const & path) const106 Reference<DirectoryLayer> DirectorySubspace::getDirectoryLayerForPath(Path const& path) const { 107 return directoryLayer; 108 } 109 } 110