hrev46286 adds 5 changesets to branch 'master' old head: 2be66b5125f0ff7bf653463f391c9cafcf0d8185 new head: 3f40dcb6b457b3560ba6e5c190e52b18b5531bc2 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=3f40dcb+%5E2be66b5 ---------------------------------------------------------------------------- 06064b9: RangeArray::AddRange(): Fix joining with single subsequent range When joining with a single range, firstRange would be the same as RangeAt(endIndex - 1) and we would overwrite its offset field before getting its end offset, thus possibly resulting in a wrong joined range size. e07b8bd: package kit: ReaderImplBase: Add public attrs section accessor b8f713e: PackageReaderImpl: Add public TOC section accessor c9ed1ea: PackageWriterImpl: Fix package file heap leak on update _Init(): In update mode remove the package attributes section and the TOC section from the package file's heap. We write the updated sections in Finish(); previously the space for the old sections would be leaked. This was also the reason why updating haiku_loader would result in a non-bootable image. 3f40dcb: PackageWriterImpl::_AttributeRemoved(): Update string cache When removing a string attribute, decrement the referenced string's usage count in the string cache. This fixes the potentially incorrect usage counts in update mode. Not a serious problem, but it could lead to only singly (or no longer) used strings to be written to the string subsection instead of encoding them inline and thus to slightly greater file sizes. [ Ingo Weinhold <ingo_weinhold@xxxxxx> ] ---------------------------------------------------------------------------- 6 files changed, 45 insertions(+), 15 deletions(-) headers/private/package/hpkg/PackageReaderImpl.h | 3 +++ headers/private/package/hpkg/ReaderImplBase.h | 4 ++++ headers/private/package/hpkg/Strings.h | 10 ++++---- headers/private/shared/RangeArray.h | 4 ++-- src/kits/package/hpkg/PackageWriterImpl.cpp | 25 ++++++++++++++------ src/kits/package/hpkg/Strings.cpp | 14 ++++++++++- ############################################################################ Commit: 06064b9b4f15ef26d0f5fb32a71e168bb14bc414 URL: http://cgit.haiku-os.org/haiku/commit/?id=06064b9 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Fri Oct 25 20:37:58 2013 UTC RangeArray::AddRange(): Fix joining with single subsequent range When joining with a single range, firstRange would be the same as RangeAt(endIndex - 1) and we would overwrite its offset field before getting its end offset, thus possibly resulting in a wrong joined range size. ---------------------------------------------------------------------------- diff --git a/headers/private/shared/RangeArray.h b/headers/private/shared/RangeArray.h index c775d6d..72ee3ef 100644 --- a/headers/private/shared/RangeArray.h +++ b/headers/private/shared/RangeArray.h @@ -142,10 +142,10 @@ RangeArray<Value>::AddRange(const Value& offset, const Value& size) // Joining is possible. We'll adjust the first affected range and remove the // others (if any). + endOffset = std::max(endOffset, RangeAt(endIndex - 1).EndOffset()); RangeType& firstRange = _RangeAt(index); firstRange.offset = std::min(firstRange.offset, offset); - firstRange.size = std::max(endOffset, RangeAt(endIndex - 1).EndOffset()) - - firstRange.offset;; + firstRange.size = endOffset - firstRange.offset; if (index + 1 < endIndex) RemoveRanges(index + 1, endIndex - index - 1); ############################################################################ Commit: e07b8bd2df230fca16cfc21aae6a554b73d120af URL: http://cgit.haiku-os.org/haiku/commit/?id=e07b8bd Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Fri Oct 25 20:39:23 2013 UTC package kit: ReaderImplBase: Add public attrs section accessor ---------------------------------------------------------------------------- diff --git a/headers/private/package/hpkg/ReaderImplBase.h b/headers/private/package/hpkg/ReaderImplBase.h index 0363749..9d04175 100644 --- a/headers/private/package/hpkg/ReaderImplBase.h +++ b/headers/private/package/hpkg/ReaderImplBase.h @@ -64,6 +64,10 @@ struct PackageFileSection { class ReaderImplBase { +public: + inline const PackageFileSection& PackageAttributesSection() const + { return fPackageAttributesSection; } + protected: ReaderImplBase(const char* fileType, BErrorOutput* errorOutput); ############################################################################ Commit: b8f713e9049a6d3cb7b7f1b5392cd181a5eb7e14 URL: http://cgit.haiku-os.org/haiku/commit/?id=b8f713e Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Fri Oct 25 20:39:39 2013 UTC PackageReaderImpl: Add public TOC section accessor ---------------------------------------------------------------------------- diff --git a/headers/private/package/hpkg/PackageReaderImpl.h b/headers/private/package/hpkg/PackageReaderImpl.h index 5ef4e08..aaac66c 100644 --- a/headers/private/package/hpkg/PackageReaderImpl.h +++ b/headers/private/package/hpkg/PackageReaderImpl.h @@ -45,6 +45,9 @@ public: BAbstractBufferedDataReader* HeapReader() const { return inherited::HeapReader(); } + inline const PackageFileSection& TOCSection() const + { return fTOCSection; } + protected: // from ReaderImplBase virtual status_t ReadAttributeValue(uint8 type, uint8 encoding, ############################################################################ Commit: c9ed1ea292780eb14b2652974c2623cc7ed0574f URL: http://cgit.haiku-os.org/haiku/commit/?id=c9ed1ea Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Fri Oct 25 20:46:41 2013 UTC PackageWriterImpl: Fix package file heap leak on update _Init(): In update mode remove the package attributes section and the TOC section from the package file's heap. We write the updated sections in Finish(); previously the space for the old sections would be leaked. This was also the reason why updating haiku_loader would result in a non-bootable image. ---------------------------------------------------------------------------- diff --git a/src/kits/package/hpkg/PackageWriterImpl.cpp b/src/kits/package/hpkg/PackageWriterImpl.cpp index 8985e50..cf2dd50 100644 --- a/src/kits/package/hpkg/PackageWriterImpl.cpp +++ b/src/kits/package/hpkg/PackageWriterImpl.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@xxxxxx. * Copyright 2011, Oliver Tappe <zooey@xxxxxxxxxxxxxxx> * Distributed under the terms of the MIT License. */ @@ -457,6 +457,7 @@ PackageWriterImpl::PackageWriterImpl(BPackageWriterListener* listener) PackageWriterImpl::~PackageWriterImpl() { + delete fHeapRangesToRemove; delete fRootAttribute; delete fRootEntry; } @@ -561,9 +562,6 @@ status_t PackageWriterImpl::Finish() { try { - RangeArray<uint64> heapRangesToRemove; - fHeapRangesToRemove = &heapRangesToRemove; - if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) { _UpdateCheckEntryCollisions(); @@ -590,8 +588,6 @@ PackageWriterImpl::Finish() if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) _CompactHeap(); - fHeapRangesToRemove = NULL; - return _Finish(); } catch (status_t error) { return error; @@ -622,6 +618,8 @@ PackageWriterImpl::_Init(const char* fileName, fHeapOffset = fHeaderSize = sizeof(hpkg_header); fTopAttribute = fRootAttribute; + fHeapRangesToRemove = new RangeArray<uint64>; + // in update mode, parse the TOC if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) { PackageReaderImpl packageReader(fListener); @@ -638,6 +636,18 @@ PackageWriterImpl::_Init(const char* fileName, return result; fHeapWriter->Reinit(packageReader.RawHeapReader()); + + // Remove the old packages attributes and TOC section from the heap. + // We'll write new ones later. + const PackageFileSection& attributesSection + = packageReader.PackageAttributesSection(); + const PackageFileSection& tocSection = packageReader.TOCSection(); + if (!fHeapRangesToRemove->AddRange(attributesSection.offset, + attributesSection.uncompressedLength) + || !fHeapRangesToRemove->AddRange(tocSection.offset, + tocSection.uncompressedLength)) { + throw std::bad_alloc(); + } } return B_OK; ############################################################################ Revision: hrev46286 Commit: 3f40dcb6b457b3560ba6e5c190e52b18b5531bc2 URL: http://cgit.haiku-os.org/haiku/commit/?id=3f40dcb Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Fri Oct 25 20:53:25 2013 UTC PackageWriterImpl::_AttributeRemoved(): Update string cache When removing a string attribute, decrement the referenced string's usage count in the string cache. This fixes the potentially incorrect usage counts in update mode. Not a serious problem, but it could lead to only singly (or no longer) used strings to be written to the string subsection instead of encoding them inline and thus to slightly greater file sizes. ---------------------------------------------------------------------------- diff --git a/headers/private/package/hpkg/Strings.h b/headers/private/package/hpkg/Strings.h index afdbd82..dcd4da9 100644 --- a/headers/private/package/hpkg/Strings.h +++ b/headers/private/package/hpkg/Strings.h @@ -1,5 +1,5 @@ /* - * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@xxxxxx. * Distributed under the terms of the MIT License. */ #ifndef _PACKAGE__HPKG__PRIVATE__STRINGS_H_ @@ -89,11 +89,11 @@ struct CachedStringUsageGreater { struct StringCache : public CachedStringTable { - StringCache(); - ~StringCache(); - - CachedString* Get(const char* value); + StringCache(); + ~StringCache(); + CachedString* Get(const char* value); + void Put(CachedString* string); }; diff --git a/src/kits/package/hpkg/PackageWriterImpl.cpp b/src/kits/package/hpkg/PackageWriterImpl.cpp index cf2dd50..7d52ed9 100644 --- a/src/kits/package/hpkg/PackageWriterImpl.cpp +++ b/src/kits/package/hpkg/PackageWriterImpl.cpp @@ -1052,7 +1052,8 @@ PackageWriterImpl::_AttributeRemoved(Attribute* attribute) && value.encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP) { if (!fHeapRangesToRemove->AddRange(value.data.offset, value.data.size)) throw std::bad_alloc(); - } + } else if (value.type == B_HPKG_ATTRIBUTE_TYPE_STRING) + fStringCache.Put(value.string); for (DoublyLinkedList<Attribute>::Iterator it = attribute->children.GetIterator(); diff --git a/src/kits/package/hpkg/Strings.cpp b/src/kits/package/hpkg/Strings.cpp index 4f87d8e..32210fd 100644 --- a/src/kits/package/hpkg/Strings.cpp +++ b/src/kits/package/hpkg/Strings.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@xxxxxx. * Distributed under the terms of the MIT License. */ @@ -70,6 +70,18 @@ StringCache::Get(const char* value) } +void +StringCache::Put(CachedString* string) +{ + if (string != NULL) { + if (--string->usageCount == 0) { + Remove(string); + delete string; + } + } +} + + } // namespace BPrivate } // namespace BHPKG