Petr Onderka has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/72148


Change subject: started writing indexes to file
......................................................................

started writing indexes to file

Change-Id: I9de3fb6829cee73dccea854700ede2cf120d577a
---
M Dump.cpp
M Dump.h
M DumpObject.cpp
M DumpObject.h
A DumpTraits.cpp
A DumpTraits.h
M FileHeader.cpp
M FileHeader.h
M Incremental dumps.vcxproj
A Index.h
A Index.hpp
A IndexLeafNode.h
A IndexLeafNode.hpp
A IndexNode.h
A IndexNode.hpp
M Offset.cpp
M Offset.h
A SpaceManager.cpp
A SpaceManager.h
M main.cpp
20 files changed, 506 insertions(+), 47 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/dumps/incremental 
refs/changes/48/72148/1

diff --git a/Dump.cpp b/Dump.cpp
index 5a0d77f..5e469c5 100644
--- a/Dump.cpp
+++ b/Dump.cpp
@@ -1,11 +1,11 @@
-#include <cstdint>
 #include <memory>
 #include <string>
 #include <fstream>
 #include "Dump.h"
 
-using std::unique_ptr;
 using std::move;
+using std::unique_ptr;
+using std::make_shared;
 using std::string;
 using std::fstream;
 using std::ios;
@@ -17,6 +17,11 @@
 ReadableDump::ReadableDump(string fileName)
     : stream(unique_ptr<fstream>(new fstream(fileName, ios::in | ios::binary)))
 {}
+
+weak_ptr<WritableDump> ReadableDump::GetSelf() const
+{
+    return self;
+}
 
 unique_ptr<iostream> WritableDump::openStream(string fileName)
 {
@@ -35,15 +40,32 @@
 
 WritableDump::WritableDump(string fileName)
     : ReadableDump(openStream(fileName))
+{}
+
+void WritableDump::init(weak_ptr<WritableDump> self)
 {
+    this->self = self;
+
     if (stream->peek() == EOF)
     {
         stream->clear();
-        fileHeader = FileHeader();
-        fileHeader.Write(stream, 0);
+        fileHeader = FileHeader(self);
+        fileHeader.Write();
     }
     else
     {
-        fileHeader = FileHeader::Read(stream);
+        fileHeader = FileHeader::Read(*this);
     }
+
+    spaceManager = SpaceManager(self);
+
+    pageIdIndex = unique_ptr<Index<int32_t, Offset>>(
+        new Index<int32_t, Offset>(self, shared_ptr<Offset>(self.lock(), 
&fileHeader.PageIdIndexRoot)));
+}
+
+shared_ptr<WritableDump> WritableDump::Create(string fileName)
+{
+    shared_ptr<WritableDump> dump(new WritableDump(fileName));
+    dump->init(dump);
+    return dump;
 }
\ No newline at end of file
diff --git a/Dump.h b/Dump.h
index e995d1b..be7ab76 100644
--- a/Dump.h
+++ b/Dump.h
@@ -5,9 +5,13 @@
 #include <string>
 #include <iostream>
 #include "FileHeader.h"
+#include "SpaceManager.h"
+#include "Index.h"
 
+using std::int32_t;
 using std::int64_t;
 using std::unique_ptr;
+using std::shared_ptr;
 using std::string;
 using std::iostream;
 
@@ -15,21 +19,34 @@
 {
 };
 
+class WritableDump;
+
 class ReadableDump
 {
 protected:
-    unique_ptr<iostream> stream;
+    weak_ptr<WritableDump> self;
+
     ReadableDump(unique_ptr<iostream> stream);
 public:
+    // TODO: others should not be able to steal this stream
+    unique_ptr<iostream> stream;
+    unique_ptr<Index<int32_t, Offset>> pageIdIndex;
+
     ReadableDump(string fileName);
+
+    weak_ptr<WritableDump> GetSelf() const;
 };
 
 class WritableDump : public ReadableDump
 {
 private:
-    FileHeader fileHeader;
-
     static unique_ptr<iostream> openStream(string fileName);
-public:
+
     WritableDump(string fileName);
+    void init(weak_ptr<WritableDump> self);
+public:
+    static shared_ptr<WritableDump> Create(string fileName);
+
+    FileHeader fileHeader;
+    SpaceManager spaceManager;
 };
\ No newline at end of file
diff --git a/DumpObject.cpp b/DumpObject.cpp
index ce6715f..1b261c4 100644
--- a/DumpObject.cpp
+++ b/DumpObject.cpp
@@ -1,7 +1,31 @@
 #include "DumpObject.h"
+#include "Dump.h"
 
-void DumpObject::Write(unique_ptr<iostream> const &stream, int64_t offset)
+DumpObject::DumpObject(weak_ptr<WritableDump> dump)
+    : dump(dump), savedOffset(0), savedLength(0)
+{}
+
+void DumpObject::Write()
 {
-    stream->seekp(offset);
-    WriteInternal(stream);
+    auto dumpRef = dump.lock();
+    auto &spaceManager = dumpRef->spaceManager;
+
+    if (savedOffset != 0)
+        spaceManager.Delete(savedOffset);
+
+    int64_t newLength = NewLength();
+    int64_t newOffset = spaceManager.GetSpace(newLength);
+
+    ostream& stream = *(dumpRef->stream);
+    stream.seekp(newOffset);
+
+    Write(stream);
+
+    savedOffset = newOffset;
+    savedLength = newLength;
+}
+
+int64_t DumpObject::SavedOffset()
+{
+    return savedOffset;
 }
\ No newline at end of file
diff --git a/DumpObject.h b/DumpObject.h
index f7b5c2f..42e6e83 100644
--- a/DumpObject.h
+++ b/DumpObject.h
@@ -4,14 +4,25 @@
 #include <memory>
 #include <iostream>
 
+class WritableDump;
+
 using std::int64_t;
 using std::unique_ptr;
-using std::iostream;
+using std::weak_ptr;
+using std::ostream;
 
 class DumpObject
 {
 protected:
-    virtual void WriteInternal(unique_ptr<iostream> const &stream) = 0;
+    weak_ptr<WritableDump> dump;
+    int64_t savedOffset;
+    int64_t savedLength;
+
+    DumpObject(weak_ptr<WritableDump> dump);
+    virtual void Write(ostream &stream) = 0;
+
 public:
-    void Write(unique_ptr<iostream> const &stream, int64_t offset);
+    virtual void Write();
+    virtual int64_t NewLength() = 0;
+    int64_t SavedOffset();
 };
\ No newline at end of file
diff --git a/DumpTraits.cpp b/DumpTraits.cpp
new file mode 100644
index 0000000..2efa999
--- /dev/null
+++ b/DumpTraits.cpp
@@ -0,0 +1 @@
+#include "DumpTraits.h"
diff --git a/DumpTraits.h b/DumpTraits.h
new file mode 100644
index 0000000..434ff93
--- /dev/null
+++ b/DumpTraits.h
@@ -0,0 +1,87 @@
+#pragma once
+
+#include <cstdint>
+#include <iostream>
+
+using std::int32_t;
+using std::istream;
+using std::ostream;
+
+template<typename T>
+class DumpTraits
+{
+public:
+    static T Read(istream &stream)
+    {
+        return T::Read(stream);
+    }
+
+    static void Write(ostream &stream, const T value)
+    {
+        value.Write(stream);
+    }
+
+    static int64_t DumpSize()
+    {
+        return T::DumpSize();
+    }
+};
+
+template<>
+class DumpTraits<int32_t>
+{
+public:
+    static int32_t Read(istream &stream)
+    {
+        char bytes[4];
+
+        stream.read(bytes, 4);
+
+        int32_t result = 0;
+        result |= (int64_t)bytes[0];
+        result |= (int64_t)bytes[1] << 8;
+        result |= (int64_t)bytes[2] << 16;
+        result |= (int64_t)bytes[3] << 24;
+
+        return result;
+    }
+
+    static void Write(ostream &stream, const int32_t value)
+    {
+        char bytes[4];
+
+        bytes[0] = value & 0xFF;
+        bytes[1] = (value >> 8) & 0xFF;
+        bytes[2] = (value >> 16) & 0xFF;
+        bytes[3] = (value >> 24) & 0xFF;
+
+        stream.write(bytes, 4);
+    }
+
+    static int64_t DumpSize()
+    {
+        return 4;
+    }
+};
+
+template<>
+class DumpTraits<char>
+{
+public:
+    static char Read(istream &stream)
+    {
+        char byte;
+        stream.read(&byte, 1);
+        return byte;
+    }
+
+    static void Write(ostream &stream, const char value)
+    {
+        stream.write(&value, 1);
+    }
+
+    static int64_t DumpSize()
+    {
+        return 1;
+    }
+};
\ No newline at end of file
diff --git a/FileHeader.cpp b/FileHeader.cpp
index ddee2dc..960e129 100644
--- a/FileHeader.cpp
+++ b/FileHeader.cpp
@@ -1,37 +1,51 @@
 #include "FileHeader.h"
 #include "Dump.h"
 
-FileHeader::FileHeader(Offset fileEnd, Offset pageIdIndexRoot, Offset 
freeSpaceIndexRoot)
-    : FileEnd(fileEnd), PageIdIndexRoot(pageIdIndexRoot), 
FreeSpaceIndexRoot(freeSpaceIndexRoot)
-{
-}
+FileHeader::FileHeader(Offset fileEnd, Offset pageIdIndexRoot, Offset 
freeSpaceIndexRoot, weak_ptr<WritableDump> dump)
+    : DumpObject(dump), FileEnd(fileEnd), PageIdIndexRoot(pageIdIndexRoot), 
FreeSpaceIndexRoot(freeSpaceIndexRoot)
+{}
 
-void FileHeader::WriteInternal(unique_ptr<iostream> const &stream)
+void FileHeader::Write(ostream &stream)
 {
-    stream->write("WMID", 4);
-    stream->write(&FileFormatVersion, 1);
-    stream->write(&FileDataVersion, 1);
+    stream.write("WMID", 4);
+    stream.write(&FileFormatVersion, 1);
+    stream.write(&FileDataVersion, 1);
 
     FileEnd.Write(stream);
     PageIdIndexRoot.Write(stream);
     FreeSpaceIndexRoot.Write(stream);
 }
 
-FileHeader FileHeader::Read(unique_ptr<iostream> const &stream)
+void FileHeader::Write()
 {
+    auto dumpRef = dump.lock();
+    ostream &stream = *(dumpRef->stream);
+
+    stream.seekp(0);
+    Write(stream);
+}
+
+FileHeader FileHeader::Read(ReadableDump const &dump)
+{
+    istream &stream = *(dump.stream);
+
     char bytes[6];
-    stream->read(bytes, 6);
-    if (stream->fail() || strncmp(bytes, "WMID", 4) != 0 || bytes[4] != 
FileFormatVersion || bytes[5] != FileDataVersion)
+    stream.read(bytes, 6);
+    if (strncmp(bytes, "WMID", 4) != 0 || bytes[4] != FileFormatVersion || 
bytes[5] != FileDataVersion)
         throw new DumpException();
 
     Offset fileEnd = Offset::Read(stream);
     Offset pageIdIndexRoot = Offset::Read(stream);
     Offset freeSpaceIndexRoot = Offset::Read(stream);
 
-    return FileHeader(fileEnd, pageIdIndexRoot, freeSpaceIndexRoot);
+    return FileHeader(fileEnd, pageIdIndexRoot, freeSpaceIndexRoot, 
dump.GetSelf());
 }
 
-FileHeader::FileHeader()
-    : FileEnd(0), PageIdIndexRoot(0), FreeSpaceIndexRoot(0)
+int64_t FileHeader::NewLength()
 {
-}
\ No newline at end of file
+    return 6 + 3 * 6;
+}
+
+FileHeader::FileHeader(weak_ptr<WritableDump> dump)
+    : DumpObject(dump), FileEnd(6 + 3 * 6), PageIdIndexRoot(0), 
FreeSpaceIndexRoot(0)
+{}
\ No newline at end of file
diff --git a/FileHeader.h b/FileHeader.h
index 20e1bb1..f0196b7 100644
--- a/FileHeader.h
+++ b/FileHeader.h
@@ -4,23 +4,28 @@
 #include "DumpObject.h"
 #include "Offset.h"
 
+class ReadableDump;
+
 using std::istream;
 
 class FileHeader : public DumpObject
 {
 private:
-    FileHeader(Offset fileEnd, Offset pageIdIndexRoot, Offset 
freeSpaceIndexRoot);
+    FileHeader(Offset fileEnd, Offset pageIdIndexRoot, Offset 
freeSpaceIndexRoot, weak_ptr<WritableDump> dump = weak_ptr<WritableDump>());
 protected:
-    virtual void WriteInternal(unique_ptr<iostream> const &stream);
+    virtual void Write(ostream &stream);
 public:
     static const char FileFormatVersion = 1;
     static const char FileDataVersion = 1;
 
-    static FileHeader Read(unique_ptr<iostream> const &stream);
+    static FileHeader Read(ReadableDump const &dump);
+
+    virtual void Write();
+    virtual int64_t NewLength();
 
     Offset FileEnd;
     Offset PageIdIndexRoot;
     Offset FreeSpaceIndexRoot;
 
-    FileHeader();
+    FileHeader(weak_ptr<WritableDump> dump = weak_ptr<WritableDump>());
 };
\ No newline at end of file
diff --git a/Incremental dumps.vcxproj b/Incremental dumps.vcxproj
index 63131ae..234f65c 100644
--- a/Incremental dumps.vcxproj
+++ b/Incremental dumps.vcxproj
@@ -80,9 +80,20 @@
   <ItemGroup>
     <ClCompile Include="Dump.cpp" />
     <ClCompile Include="DumpObject.cpp" />
+    <ClCompile Include="DumpTraits.cpp" />
     <ClCompile Include="FileHeader.cpp" />
+    <ClInclude Include="Index.h" />
+    <ClInclude Include="IndexLeafNode.hpp">
+      <FileType>CppCode</FileType>
+    </ClInclude>
+    <ClInclude Include="IndexNode.hpp">
+      <ExcludedFromBuild 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
+      <FileType>CppCode</FileType>
+    </ClInclude>
+    <ClInclude Include="Index.hpp" />
     <ClCompile Include="main.cpp" />
     <ClCompile Include="Offset.cpp" />
+    <ClCompile Include="SpaceManager.cpp" />
     <ClCompile Include="TestDumpWriter.cpp" />
     <ClCompile Include="XmlPageProcessor.cpp" />
     <ClCompile Include="XmlRevisionProcessor.cpp" />
@@ -96,11 +107,15 @@
   <ItemGroup>
     <ClInclude Include="Dump.h" />
     <ClInclude Include="DumpObject.h" />
+    <ClInclude Include="DumpTraits.h" />
     <ClInclude Include="DumpWriter.h" />
     <ClInclude Include="FileHeader.h" />
+    <ClInclude Include="IndexLeafNode.h" />
+    <ClInclude Include="IndexNode.h" />
     <ClInclude Include="Offset.h" />
     <ClInclude Include="Page.h" />
     <ClInclude Include="Revision.h" />
+    <ClInclude Include="SpaceManager.h" />
     <ClInclude Include="TestDumpWriter.h" />
     <ClInclude Include="XmlPageProcessor.h" />
     <ClInclude Include="XmlRevisionProcessor.h" />
diff --git a/Index.h b/Index.h
new file mode 100644
index 0000000..64cab2e
--- /dev/null
+++ b/Index.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "Offset.h"
+#include "IndexNode.h"
+
+template<typename TKey, typename TValue>
+class Index
+{
+private:
+    unique_ptr<IndexNode<TKey, TValue>> rootNode;
+    weak_ptr<WritableDump> dump;
+    weak_ptr<Offset> fileHeaderOffset;
+public:
+    Index(weak_ptr<WritableDump> dump, weak_ptr<Offset> fileHeaderOffset);
+
+    TValue operator[](TKey key);
+    void Add(TKey key, TValue value);
+};
+
+#include "Index.hpp"
\ No newline at end of file
diff --git a/Index.hpp b/Index.hpp
new file mode 100644
index 0000000..69b82ae
--- /dev/null
+++ b/Index.hpp
@@ -0,0 +1,33 @@
+#include "Index.h"
+
+template<typename TKey, typename TValue>
+Index<TKey, TValue>::Index(weak_ptr<WritableDump> dump, weak_ptr<Offset> 
fileHeaderOffset)
+    : dump(dump), fileHeaderOffset(fileHeaderOffset)
+{
+    auto offset = fileHeaderOffset.lock()->value;
+
+    if (offset == 0)
+        rootNode = IndexNode<TKey, TValue>::CreateNew(dump);
+    else
+        rootNode = IndexNode<TKey, TValue>::Read(dump, offset);
+}
+
+template<typename TKey, typename TValue>
+TValue Index<TKey, TValue>::operator[](TKey key)
+{
+    return (*rootNode)[key];
+}
+
+template<typename TKey, typename TValue>
+void Index<TKey, TValue>::Add(TKey key, TValue value)
+{
+    rootNode->Add(key, value);
+
+    auto offset = fileHeaderOffset.lock();
+
+    if (rootNode->SavedOffset() != offset->value)
+    {
+        offset->value = rootNode->SavedOffset();
+        dump.lock()->fileHeader.Write();
+    }
+}
\ No newline at end of file
diff --git a/IndexLeafNode.h b/IndexLeafNode.h
new file mode 100644
index 0000000..9ff696b
--- /dev/null
+++ b/IndexLeafNode.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <map>
+#include "IndexNode.h"
+
+using std::map;
+
+template<typename TKey, typename TValue>
+class IndexLeafNode : public IndexNode<TKey, TValue>
+{
+private:
+    map<TKey, TValue> map;
+protected:
+    virtual void Write(ostream &stream);
+public:
+    static unique_ptr<IndexNode> Read(weak_ptr<WritableDump> dump, istream 
&stream);
+
+    IndexLeafNode(weak_ptr<WritableDump> dump);
+
+    using DumpObject::Write;
+    virtual int64_t NewLength();
+
+    virtual TValue operator[](TKey key);
+    virtual void Add(TKey key, TValue value);
+};
+
+#include "IndexLeafNode.hpp"
\ No newline at end of file
diff --git a/IndexLeafNode.hpp b/IndexLeafNode.hpp
new file mode 100644
index 0000000..5196744
--- /dev/null
+++ b/IndexLeafNode.hpp
@@ -0,0 +1,69 @@
+#include <utility>
+#include "DumpTraits.h"
+
+using std::pair;
+
+template<typename TKey, typename TValue>
+TValue IndexLeafNode<TKey, TValue>::operator[](TKey key)
+{
+    return map.find(key)->second;
+}
+
+template<typename TKey, typename TValue>
+void IndexLeafNode<TKey, TValue>::Add(TKey key, TValue value)
+{
+    map.insert(pair<TKey, TValue>(key, value));
+    Write();
+}
+
+template<typename TKey, typename TValue>
+IndexLeafNode<TKey, TValue>::IndexLeafNode(weak_ptr<WritableDump> dump)
+    : IndexNode(dump)
+{
+}
+
+template<typename TKey, typename TValue>
+unique_ptr<IndexNode<TKey, TValue>> IndexLeafNode<TKey, 
TValue>::Read(weak_ptr<WritableDump> dump, istream &stream)
+{
+    auto node = new IndexLeafNode<TKey, TValue>(dump);
+
+    char count = DumpTraits<char>::Read(stream);
+
+    unique_ptr<TKey[]> keys(new TKey[count]);
+
+    for (int i = 0; i < count; i++)
+    {
+        keys[i] = DumpTraits<TKey>::Read(stream);
+    }
+
+    for (int i = 0; i < count; i++)
+    {
+        node->map.insert(pair<TKey, TValue>(keys[i], 
DumpTraits<TValue>::Read(stream)));
+    }
+
+    return unique_ptr<IndexNode<TKey, TValue>>(node);
+}
+
+template<typename TKey, typename TValue>
+void IndexLeafNode<TKey, TValue>::Write(ostream &stream)
+{
+    DumpTraits<char>::Write(stream, (char)NodeKind::LeafNode);
+       DumpTraits<char>::Write(stream, map.size());
+
+       for (auto pair : map)
+    {
+               DumpTraits<TKey>::Write(stream, pair.first);
+    }
+
+       for (auto pair : map)
+    {
+               DumpTraits<TValue>::Write(stream, pair.second);
+    }
+}
+
+template<typename TKey, typename TValue>
+int64_t IndexLeafNode<TKey, TValue>::NewLength()
+{
+    return DumpTraits<char>::DumpSize()
+        + map.size() * (DumpTraits<TKey>::DumpSize() + 
DumpTraits<TValue>::DumpSize());
+}
\ No newline at end of file
diff --git a/IndexNode.h b/IndexNode.h
new file mode 100644
index 0000000..ff54e3a
--- /dev/null
+++ b/IndexNode.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "DumpObject.h"
+
+template<typename TKey, typename TValue>
+class IndexNode : public DumpObject
+{
+protected:
+    virtual void Write(ostream &stream) = 0;
+
+    enum class NodeKind : char
+    {
+        LeafNode = 1
+    };
+
+public:
+    static unique_ptr<IndexNode> Read(weak_ptr<WritableDump> dump, int64_t 
offset);
+    static unique_ptr<IndexNode> CreateNew(weak_ptr<WritableDump> dump);
+
+    IndexNode(weak_ptr<WritableDump> dump);
+
+    using DumpObject::Write;
+
+    virtual TValue operator[](TKey key) = 0;
+    virtual void Add(TKey key, TValue value) = 0;
+    // TODO:
+    //virtual void Remove(TKey key);
+    //virtual void Remove(TKey key, TValue value); // required for memory index
+};
+
+#include "IndexNode.hpp"
\ No newline at end of file
diff --git a/IndexNode.hpp b/IndexNode.hpp
new file mode 100644
index 0000000..9dde998
--- /dev/null
+++ b/IndexNode.hpp
@@ -0,0 +1,33 @@
+#include "IndexNode.h"
+#include "IndexLeafNode.h"
+
+template<typename TKey, typename TValue>
+IndexNode<TKey, TValue>::IndexNode(weak_ptr<WritableDump> dump)
+    : DumpObject(dump)
+{}
+
+template<typename TKey, typename TValue>
+unique_ptr<IndexNode<TKey, TValue>> IndexNode<TKey, 
TValue>::Read(weak_ptr<WritableDump> dump, int64_t offset)
+{
+    auto dumpRef = dump.lock();
+    auto &stream = *(dumpRef->stream);
+    stream.seekp(offset);
+
+    char byte;
+    stream.read(&byte, 1);
+    if (byte == (char)NodeKind::LeafNode)
+    {
+        auto result = IndexLeafNode<TKey, TValue>::Read(dump, stream);
+        result->savedOffset = offset;
+        result->savedLength = result->NewLength();
+        return result;
+    }
+    else
+        throw new DumpException();
+}
+
+template<typename TKey, typename TValue>
+unique_ptr<IndexNode<TKey, TValue>> IndexNode<TKey, 
TValue>::CreateNew(weak_ptr<WritableDump> dump)
+{
+    return unique_ptr<IndexNode<TKey, TValue>>(new IndexLeafNode<TKey, 
TValue>(dump));
+}
\ No newline at end of file
diff --git a/Offset.cpp b/Offset.cpp
index d6097e0..6eaaebf 100644
--- a/Offset.cpp
+++ b/Offset.cpp
@@ -8,7 +8,7 @@
         throw DumpException();
 }
 
-void Offset::Write(unique_ptr<iostream> const &stream) const
+void Offset::Write(ostream &stream) const
 {
     char bytes[6];
 
@@ -19,17 +19,14 @@
     bytes[4] = (value >> 32) & 0xFF;
     bytes[5] = (value >> 40) & 0xFF;
 
-    stream->write(bytes, 6);
+    stream.write(bytes, 6);
 }
 
-Offset Offset::Read(unique_ptr<iostream> const &stream)
+Offset Offset::Read(istream &stream)
 {
     char bytes[6];
 
-    stream->read(bytes, 6);
-
-    if (stream->fail())
-        throw new DumpException();
+    stream.read(bytes, 6);
 
     int64_t offset = 0;
     offset |= (int64_t)bytes[0];
@@ -40,4 +37,9 @@
     offset |= (int64_t)bytes[5] << 40;
 
     return Offset(offset);
+}
+
+int64_t Offset::DumpSize()
+{
+    return 6;
 }
\ No newline at end of file
diff --git a/Offset.h b/Offset.h
index f0f451a..588c226 100644
--- a/Offset.h
+++ b/Offset.h
@@ -6,7 +6,8 @@
 
 using std::int64_t;
 using std::unique_ptr;
-using std::iostream;
+using std::istream;
+using std::ostream;
 
 class Offset
 {
@@ -14,6 +15,7 @@
     int64_t value;
 
     Offset(int64_t value);
-    void Write(unique_ptr<iostream> const &stream) const;
-    static Offset Read(unique_ptr<iostream> const &stream);
+    void Write(ostream &stream) const;
+    static Offset Read(istream &stream);
+    static int64_t DumpSize();
 };
\ No newline at end of file
diff --git a/SpaceManager.cpp b/SpaceManager.cpp
new file mode 100644
index 0000000..f8a0c38
--- /dev/null
+++ b/SpaceManager.cpp
@@ -0,0 +1,25 @@
+#include "SpaceManager.h"
+#include "Dump.h"
+
+SpaceManager::SpaceManager(weak_ptr<WritableDump> dump)
+    : dump(dump)
+{}
+
+int64_t SpaceManager::GetSpace(int64_t length)
+{
+    // TODO: find free space
+
+    auto dumpRef = dump.lock();
+    auto &header = dumpRef->fileHeader;
+    int64_t offset = header.FileEnd.value;
+    header.FileEnd.value += length;
+    header.Write();
+
+    return offset;
+}
+
+void SpaceManager::Delete(int64_t offset)
+{
+    // TODO
+    throw new DumpException();
+}
\ No newline at end of file
diff --git a/SpaceManager.h b/SpaceManager.h
new file mode 100644
index 0000000..4228f9f
--- /dev/null
+++ b/SpaceManager.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <cstdint>
+#include <memory>
+#include "SpaceManager.h"
+
+using std::int64_t;
+using std::weak_ptr;
+
+class WritableDump;
+
+class SpaceManager
+{
+private:
+    weak_ptr<WritableDump> dump;
+public:
+    SpaceManager(weak_ptr<WritableDump> dump = weak_ptr<WritableDump>());
+    int64_t GetSpace(int64_t length);
+    void Delete(int64_t offset);
+};
\ No newline at end of file
diff --git a/main.cpp b/main.cpp
index 229b7b2..6bff684 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,12 +1,11 @@
-#include <string>
 #include <iostream>
 #include "XML/xmlinput.h"
 #include "XML/xmlfile.h"
 #include "TestDumpWriter.h"
 #include "XmlPageProcessor.h"
 #include "Dump.h"
+#include "IndexLeafNode.h"
 
-using std::string;
 using std::cin;
 
 class StandardInputStream : public XML::InputStream
@@ -45,5 +44,7 @@
 
     input.Process(handlers, &writer);*/
 
-    WritableDump dump("test.id");
+    shared_ptr<WritableDump> dump = WritableDump::Create("tmp/test.id");
+
+    dump->pageIdIndex->Add(1, 2);
 }
\ No newline at end of file

-- 
To view, visit https://gerrit.wikimedia.org/r/72148
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9de3fb6829cee73dccea854700ede2cf120d577a
Gerrit-PatchSet: 1
Gerrit-Project: operations/dumps/incremental
Gerrit-Branch: gsoc
Gerrit-Owner: Petr Onderka <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to